cozy_tui
A lightweight, cross-platform Python TUI (Terminal User Interface) library. Build keyboard-driven terminal apps with widgets, focus management, mouse support, and smooth cursor blinking — all rendered through raw VT sequences. Runs on Windows (Console API) and POSIX (Linux/macOS via termios).
Changes are tracked in CHANGELOG.md.
Documentation
Full documentation lives in docs/ (GitHub) directory:
- Core Concepts — the render loop, coordinate system, and widget lifecycle.
- Widgets — every widget:
App,Box,Label,Hyperlink,Bindings,Code,CodeInput,Text,Input,Button,Checkbox,Slider,MarkdownInput,DropFilesArea,ListView,CheckList,RadioSet,RightClickMenu,MenuBar,Dropdown,ProgressBar,Spinner,Toast,Tooltip,Table,Tabs,ScrollView,Splitter,Collapsible,Tree,AnimatedLabel,TracebackView. - Layouts, Dock & Overlays —
VBox/HBox/Grid,app.dock(...), and the overlay/modal layer (open_overlay,app.prompt,app.confirm,app.pick_file). - Styling —
Style, colors, text attributes, andThemes. - Input & Interaction — key bindings, mouse support, focus, scrolling, and the Ctrl+P command palette.
- Testing —
cozy_tui.testing.Harness: drive an app headlessly, with virtual time. - Examples — runnable demos in
examples/.
Features
- Cross-platform — runs on Windows (Console API) and POSIX (Linux/macOS via
termios); the backend is chosen automatically. - Very few dependencies — the clipboard is built in (no
pyperclip); the only third-party dependency isrich, used to renderMarkdown/MarkdownInputand to syntax-highlightTracebackView/show_traceback. Everything else is the standard library. - Built-in clipboard —
cozy_tui.clipboard.copy/pastewith native backends per platform (Win32 API,pbcopy/pbpaste,wl-clipboard/xclip/xsel, or OSC 52 fallback). - Unicode-aware rendering — a built-in
wcwidth-style width layer keeps CJK/emoji (double-width) and combining marks (zero-width) aligned in the cell grid. - Widgets:
Button,Checkbox,Input,Slider,Label,Hyperlink,Bindings,AnimatedLabel,Code,CodeInput,Text,Box,MarkdownInput,DropFilesArea,ListView,CheckList,RadioSet,RightClickMenu,MenuBar,Dropdown,ProgressBar,Spinner,Toast,Tooltip,Table,Tabs,ScrollView,Splitter,Collapsible,Tree,TracebackView - Testing harness:
cozy_tui.testing.Harnessdrives your app headlessly —ui.click(button),ui.type("hello"),assert "Saved!" in ui— with virtual time (ui.advance(30)fires a 30-second timer instantly, nothing sleeps) and no escape sequences in your test output; see testing.md - Reactive state:
State("Downloads")is an observable value — pass it as a widget'stext/title/progressand the widget follows everystate.value = ..., with one state free to drive as many widgets as you like. Explicit by design (a plainstris never reactive) and one-way; see concepts.md - Themes: a
Themebundles the accent/muted/semantic/selection colors most widgets andapp.toast(...)draw from; switch withset_theme(theme)/theme.activate(), or interactively via the Ctrl+T searchable picker (over 20 built-in presets inTheme.MODES) — see styling.md - Command palette: Ctrl+P opens a Textual-style searchable list of commands (
app.register_command(...)to add your own) — Quit, Change Theme, and Keys (a live keybindings legend) are built in - Crash screens: unhandled exceptions in
app.run()automatically show a full-screen, scrollable, syntax-highlightedTracebackViewwith one-key clipboard copy (App(catch_errors=False)to get a plain propagating exception instead); callcozy_tui.crash_screen.show_traceback(exc)directly to get the same screen outside ofrun() - Context menus:
RightClickMenuwith icons, shortcut labels, and submenus — pop it up fromapp.on_right_click(...);MenuBardocks the same building blocks to the top of the screen as a File/Edit-style menu bar - Layouts:
VBox,HBox,Grid— auto-position children without manual x/y, withflex=to grow docked children into leftover space;Splitterfor a user-resizable two-pane divider - Dock layout:
app.dock(widget, "top"/"bottom"/"left"/"right"/"fill")— edge-anchored regions that re-flow on resize - Overlays & modals:
app.open_overlay(widget)floats a widget above the UI, dims the background, and confines focus/input — the basis for dialogs (app.prompt,app.confirm,app.pick_file), menus, and tooltips (app.set_tooltip) - Input validation:
Input(inp_type="number")filters keystrokes to valid numbers as you type;required=/validator=plus.error/.is_validfor anything else, with automatic error-color styling - Multi-line Input: Enter or Shift+Enter to insert newlines, UP/DOWN to navigate lines
- Markdown preview:
MarkdownInputrenders live Rich Markdown when unfocused - Focus system: Tab / Shift+Tab to cycle focus, click to focus with mouse
- Cursor blinking: Uses the real terminal cursor — smooth blink with no character replacement
- Mouse support: Click to focus widgets, click to activate buttons, scroll wheel to scroll
- Scrolling: Long content scrolls vertically; single-line inputs scroll horizontally
- Global key handlers: Register app-wide shortcuts with
app.on_key() - Flexible styling: Per-widget foreground, background, and text styles (bold, dim, underline)
Requirements
- Python 3.10+
- A VT-capable terminal on Windows (Windows Console API) or POSIX (Linux/macOS, via
termios/tty). The console backend is selected automatically at import.
Installation
pip install cozy-tui
That's it — rich (used to render Markdown/MarkdownInput and to syntax-highlight TracebackView) is pulled in automatically.
Take it for a spin with the built-in demo:
cozy-tui # or: python -m cozy_tui
Command-line
Installing the package also provides a cozy-tui command (equivalently python -m cozy_tui):
cozy-tui # launch the interactive demo (no subcommand)
cozy-tui demo # launch the interactive demo
cozy-tui --version # print the installed version
cozy-tui doctor # check Python, imports, clipboard backend, color depth, PyPI version
cozy-tui doctor --offline # skip the PyPI check
cozy-tui info # version + detected terminal capabilities
cozy-tui run script.py # run a script, like `python script.py`
cozy-tui run --debug script.py # ...with App(debug=True) on, no code change needed
Then in your script:
from cozy_tui import App, Style
from cozy_tui.widgets import Box, Label, Input, Button
From source (for development)
git clone https://github.com/youssefahmed2017/cozy_tui.git
cd cozy_tui
pip install -e . # add [dev] for the test suite (pytest)
Quick Start
from cozy_tui import App, Style
from cozy_tui.widgets import Box, Label, Input, Button, Checkbox
from cozy_tui.events import Key
app = App(full=True, size=None, style=Style(fg="white", bg="black"))
# Box size = virtual pixels ÷ App.SCALE (10) → "600x140" = 60 cols × 14 rows
box = Box(2, 1, "600x140", border="rounded", style=Style(fg="white", bg="black"), title="Sign Up")
box.add(Label(2, 2, "Username:"))
box.add(Input(12, 2, 20, placeholder="Enter username"))
box.add(Label(2, 4, "Bio:"))
box.add(Input(12, 4, 20, placeholder="Tell us about you", multiline=True))
box.add(Checkbox(2, 7, "Subscribe to newsletter"))
box.add(Checkbox(2, 9, "I agree to the terms", checked=True))
btn = Button(2, 11, "Submit", width=20, style=Style(fg="white", bg="blue"))
btn.on_click(lambda b: print("Submitted!"))
box.add(btn)
app.add(box)
app.focus(btn)
app.on_key(Key.ESC, lambda: "quit")
app.run()
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cozy_tui-0.6.0.tar.gz.
File metadata
- Download URL: cozy_tui-0.6.0.tar.gz
- Upload date:
- Size: 374.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8db3b127b3e6cd4166f3e5866ca7687b0051287204575d9ad9e8828f2c79516a
|
|
| MD5 |
deefb738ed21f39f3513f5054b32d48c
|
|
| BLAKE2b-256 |
2189afb3271d254e846078186991db6e93424a1e96729b0d01c18ff7c4b132c1
|
File details
Details for the file cozy_tui-0.6.0-py3-none-any.whl.
File metadata
- Download URL: cozy_tui-0.6.0-py3-none-any.whl
- Upload date:
- Size: 262.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5084f7551c0f1a48a1c18cab343203bad7ab1eecc5e451914ab960a4cf524d42
|
|
| MD5 |
0148c2481b9d68fe9754fd7c7860fbb3
|
|
| BLAKE2b-256 |
de41193f8d64510199176fe2465c86d0146289e8388032adf4c11b9c73161fe0
|