▚Custom components
Built on @opentui/react — composition over inheritance. No native code, no extend() ceremony: every component below is a plain function component using <box>, <text>, and the useKeyboard / useTimeline hooks. Source in lib/custom/, runnable in examples/custom/.
~/components/data-viz
11Charts and plots rendered in character cells — line, bar, pie, gauge, heatmap and more.
Multi-row line chart with gradient fill, reveal and crosshair
LineChart with a stronger under-line gradient
Mini time-series chart with gradient fill, dot and reveal
Vertical bars with gridlines, value and category labels
Solid disc colored by share with legend
Donut with a centered total and legend
Semicircle arc with warn/danger zones and needle
Background-colored matrix with labels and gradient legend
OHLC candles with wicks, up/down colors and index labels
Multi-series dot plot with gridlines and legend
Centered shrinking bars with per-stage gradient and percent
~/components/feedback
3Progress, status and notification primitives that keep the user informed.
~/components/input
3Keyboard-driven interactive controls: editors, trees, dialogs.
~/components/layout
2Structural helpers for arranging terminal UI.
~/components/display
1Presentational one-offs that render read-only content.
~/components/agentic
6Building blocks for AI-agent CLIs: spinners, tool calls, approvals, token meters.
Neomorphic status line with spinner, sub-task and elapsed timer
Agent bottom bar: mode, model, task, clock and token counter
Invocation card: state glyph, args, duration and collapsible output
Permission dialog with keyboard yes/no and selection state
Context window usage bar with zone colors and io stats
Session plan tracker: pending → running → done with live spinner
##Usage pattern
Components import like any React module. Stateful ones (Toast, Modal) expose context or props; presentational ones (Badge, Sparkline, ProgressBar) render from props only:
1import { createCliRenderer } from "@opentui/core"2import { createRoot } from "@opentui/react"3import { Badge, ProgressBar, ToastProvider } from "termino"45function App() {6 return (7 <box border title="dashboard" style={{ padding: 2, flexDirection: "column", gap: 1 }}>8 <box flexDirection="row" gap={1}>9 <Badge label="prod" tone="red" />10 <Badge label="ready" tone="green" prefix="● " />11 </box>12 <ProgressBar label="deploy" value={64} />13 </box>14 )15}1617const renderer = await createCliRenderer()18createRoot(renderer).render(19 <ToastProvider>20 <App />21 </ToastProvider>,22)
Run any example in a real terminal:
1$ bun examples/custom/tree-view.tsx # keyboard tree2$ bun examples/custom/progress-bar.tsx # animated bars3$ bun examples/custom/toast.tsx # space to push toasts