Rezi
Rezi is a code-first terminal UI framework for Node.js and Bun. Build interactive terminal applications with a declarative widget API, automatic focus management, and native-backed rendering throug...
Rezi is a code-first terminal UI framework for Node.js and Bun. Build interactive terminal applications with a declarative widget API, automatic focus management, and native-backed rendering through the Zireael C engine.
import { ui, rgb } from "@rezi-ui/core";
import { createNodeApp } from "@rezi-ui/node";
const app = createNodeApp<{ count: number }>({
initialState: { count: 0 },
});
app.view((state) =>
ui.column({ p: 1, gap: 1 }, [
ui.text("Counter", { style: { fg: rgb(120, 200, 255), bold: true } }),
ui.row({ gap: 2 }, [
ui.text(`Count: ${state.count}`),
ui.button("inc", "+1", {
onPress: () => app.update((s) => ({ count: s.count + 1 })),
}),
]),
])
);
app.keys({ q: () => app.stop() });
await app.start();Why Rezi?
Declarative and Type-Safe : Define your UI as a function of state. Full TypeScript support with strict typing for props, state, and events.
Rich Widget Library : 50+ built-in widgets covering forms, tables, trees, modals, code editors, command palettes, charts, and more.
Native Performance : Powered by the Zireael C engine with a binary protocol boundary. No virtual DOM diffing overhead.
Focus Management : Automatic keyboard navigation with focus zones, focus traps, and modal stacking.
Mouse Support : Click to focus and activate widgets, scroll wheel for lists and editors, drag to resize split panes, click backdrops to close modals. Detected automatically — no configuration needed.
Theming : Six built-in themes (dark, light, dimmed, high-contrast, nord, dracula) with semantic color tokens.
Keybindings
: First-class support for modal keybindings with chord sequences (Vim-style g g, Emacs-style C-x C-s).
JSX Support
: Write widget trees using JSX syntax with @rezi-ui/jsx — no React required. Getting started →
Performance : See benchmarks → for methodology, limitations, and the latest committed results.
Architecture
| Layer | Purpose |
|---|---|
| @rezi-ui/core | Widgets, layout, themes, forms, keybindings. No Node.js APIs. |
| @rezi-ui/node | Node.js/Bun backend with worker and inline execution modes. |
| @rezi-ui/native | N-API addon (napi-rs) binding to the Zireael C rendering engine. |
| @rezi-ui/jsx | Optional JSX runtime for widget trees. |
Getting Started
-
Install
Install Rezi via npm and set up your first project.
-
Quickstart
Build a minimal Rezi application.
-
Widgets
Browse the complete widget catalog.
-
Styling
Themes, colors, and visual customization.
Core Concepts
State-Driven Rendering
Rezi applications are state-driven. You define a view function that returns a widget tree based on your application state:
type State = { items: string[]; selected: number };
app.view((state) =>
ui.column({ gap: 1 },
state.items.map((item, i) =>
ui.text(i === state.selected ? `> ${item}` : ` ${item}`, {
key: String(i),
})
)
)
);State Updates
Update state with app.update(). Updates are batched and coalesced for efficiency:
app.update((prev) => ({ ...prev, selected: prev.selected + 1 }));Widget Composition
Widgets compose naturally. Container widgets like column, row, and box accept children:
ui.box({ title: "User Form", p: 1 }, [
ui.field({ label: "Name", required: true, children:
ui.input({ id: "name", value: state.name })
}),
ui.row({ gap: 2 }, [
ui.button({ id: "submit", label: "Submit" }),
ui.button({ id: "cancel", label: "Cancel" }),
]),
])Focus and Navigation
Interactive widgets (buttons, inputs) automatically participate in focus navigation. Use Tab/Shift+Tab to move between focusable elements, or click any focusable widget with the mouse:
ui.column({}, [
ui.button({ id: "first", label: "First" }), // Tab stop 1
ui.button({ id: "second", label: "Second" }), // Tab stop 2
ui.input({ id: "name", value: "" }), // Tab stop 3
])Widget Categories
Primitives
Layout building blocks: text, box, row, column, spacer, divider
Form Inputs
Interactive controls: button, input, checkbox, radioGroup, select, field
Navigation
Routing and wayfinding: tabs, accordion, breadcrumb, link, pagination
Data Display
Data presentation: table, virtualList, tree, richText, badge, tag, status
Overlays
Modal UIs: modal, dropdown, layer, layers, toast, focusZone, focusTrap
Layout Components
Complex layouts: splitPane, panelGroup, resizablePanel
Advanced Widgets
Rich functionality: commandPalette, codeEditor, diffViewer, logsConsole, filePicker
Charts
Data visualization: gauge, progress, sparkline, barChart, miniChart
Graphics Components
Graphics rendering: canvas, image, lineChart, scatter, heatmap
Feedback
User feedback: spinner, skeleton, callout, errorDisplay, empty
Learn More
- Concepts - Understanding Rezi's architecture
- Ink to Rezi Migration - Mental model mapping and migration recipes
- Lifecycle & Updates - State management patterns
- Routing - Page-level navigation and screen history
- Layout - Spacing, alignment, and constraints
- Input & Focus - Keyboard navigation and focus management
- Mouse Support - Click, scroll, and drag interactions
- Styling - Colors, themes, and visual customization
- Graphics - Capability-aware rendering and progressive enhancement
- Performance - Optimization techniques
- Debugging - Debug tools and frame inspection
- Architecture - Runtime stack and data flow
- API Reference - TypeDoc-generated API docs
- Developer Guide - Local setup and workflows