| name | pi-tui |
| topic | Pi TUI Framework |
| description | Build terminal UI with @mariozechner/pi-tui — component-based TUI with differential rendering. Use when creating TUI screens, input widgets, overlays, or keybindings. |
| token_cost | 130 |
| keywords | ["pi-tui","tui","terminal","component","overlay"] |
pi-tui — Component-Based Terminal UI
Component-based TUI framework with differential rendering and synchronized output for flicker-free terminals.
Core Setup
import { TUI, ProcessTerminal } from "@mariozechner/pi-tui";
const tui = new TUI(new ProcessTerminal());
tui.addChild(component);
tui.start();
tui.stop();
Built-in Components (13 total)
| Component | Purpose | Key Methods |
|---|
Container | Holds child components | addChild(), removeChild(), clear() |
Text / TruncatedText | Plain text display | setText() |
Input | Single-line text input | getValue(), setValue() |
Editor | Multi-line text editor | setText(), getText(), getCursor() |
Markdown | Render markdown text | setText() |
SelectList | Selectable list with filtering | setFilter(), onSelect, onCancel |
SettingsList | Key-value settings editor | updateValue() |
Box | Container with background | setBgFn() |
Spacer | Vertical spacing | setLines() |
Loader / CancellableLoader | Loading spinner | start(), stop(), setMessage() |
Image | Render images (base64) | getImageId() |
Each component is its own file — import directly from the package, no barrel re-exports.
Rendering Rules
Every render(width) line must not exceed width visible columns. Use truncateToWidth(), wrapTextWithAnsi(), or visibleWidth() to enforce this. Each rendered line gets a full SGR reset appended — styles do not carry across lines.
Focusable Components
Input, Editor implement Focusable. Custom components with cursors must also implement Focusable and emit CURSOR_MARKER in render output when focused. When a container wraps an Input/Editor, propagate focus to the child for correct IME candidate window positioning.
Keybindings & Key Detection
Use matchesKey() for raw detection: matchesKey(data, Key.enter), Key.ctrl("c"), Key.shift("tab"). For user-customizable bindings, use the global KeybindingsManager via getKeybindings() — components like Editor, Input, SelectList, and SettingsList route input through named bindings.
Overlays
tui.showOverlay(component, options);
handle.hide();
handle.setHidden();
Overlays support nonCapturing mode (no keyboard focus steal) and stack with z-ordering by focusOrder.
Custom Components
Each custom component lives in its own file implementing Component. For caching, store cachedLines and cachedWidth, reset in invalidate().
See references/ for complete API reference, custom component patterns, autocomplete providers, terminal image APIs, best practices, and anti-patterns.