Skip to content

Rezi

Rezi is a code-first terminal UI framework for Node.js. Build rich, interactive terminal applications with a declarative widget API, automatic focus management, and native rendering performance.

import { createApp, ui, rgb } from "@rezi-ui/core";
import { createNodeBackend } from "@rezi-ui/node";

const app = createApp({
  backend: createNodeBackend(),
  initialState: { count: 0 },
});

app.view((state) =>
  ui.column({ p: 1, gap: 1 }, [
    ui.text("Counter", { style: { fg: rgb(120, 200, 255), bold: true } }),
    ui.button({
      id: "inc",
      label: `Count: ${state.count} (+1)`,
      onPress: () => app.update((s) => ({ count: s.count + 1 })),
    }),
  ])
);

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+ 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.
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 →
Ink Compatibility
Drop-in Ink compatibility layer (@rezi-ui/ink-compat) to run existing Ink apps on Rezi's engine. Migration guide →
Performance
1,800x–40,000x faster than Ink. Benchmark results →

Architecture

flowchart TB
    App["Application Code"] --> Core["@rezi-ui/core"]
    JSX["@rezi-ui/jsx"] -.-> Core
    InkCompat["@rezi-ui/ink-compat"] -.-> Core
    Core --> Node["@rezi-ui/node"]
    Node --> Native["@rezi-ui/native"]
    Native --> Engine["Zireael C Engine"]

    subgraph Runtime-Agnostic
        Core
    end

    subgraph Node.js Runtime
        Node
        Native
    end
Layer Purpose
@rezi-ui/core Widgets, layout, themes, forms, keybindings. No Node.js APIs.
@rezi-ui/node Node.js backend with worker thread integration.
@rezi-ui/native napi-rs binding to the Zireael C rendering engine.
@rezi-ui/jsx Optional JSX runtime for widget trees.
@rezi-ui/ink-compat Optional drop-in Ink compatibility layer (React).

Getting Started

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:

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

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

Feedback

User feedback: spinner, skeleton, callout, errorDisplay, empty

Learn More