The state-driven TUI framework for TypeScript
Build deterministic, mouse-aware, beautiful terminal applications with Elm architecture or declarative TSX, grapheme-safe text, 52 tested UI builders, sub-cell charts, and multi-window tiling.
npm create celestial@latest my-app
Preview release — the scaffolder publishes to npm at launch. Until then, clone the repo and run one of the supported demos.
Engineered for Production Terminals
Everything you need to ship reliable CLIs without terminal escape code headaches.
Elm Runtime + Signals
Deterministic Model-Update-View state loop with reactive signals (signal/computed/effect), zero side-effect view rendering, and a headless test harness that replays real apps.
Optional TSX / JSX Layer
Write declarative <Box>, <Text>, and <Button> elements with standard React-like component ergonomics.
Grapheme & Bidi Safe
True Unicode segmentation (Rosetta). Emojis, zero-width joiners, and right-to-left text never tear or corrupt terminal layout bounds.
First-Class Mouse & Focus
Full hit testing (Nexus), drag-and-drop, right-click contextual menus, scroll wheels, and keyboard focus trap rings.
AI & Agentic Ready
Progressive token-streaming Markdown, collapsible tool-call execution cards, syntax-highlighted diff viewers, and inline prompt runners.
Single Native Binary
Compile your entire TypeScript TUI into a standalone .exe, Linux ELF, or macOS executable using Node SEA or Bun compile.
Interactive Component Discovery
Every terminal pane below is a real render: docs-site/generate.mjs runs the built @celestial packages through the framework's own headless layout pipeline, and each snippet is a typechecked file from docs-site/snippets/.
Guides & Architecture
Learn how to build, test, and distribute your Celestial applications.
Migrating from React / Ink
How Celestial's Elm architecture and optional JSX layer compare to Ink's React reconciler — the same declarative element shape, driven by an explicit model-update-view loop.
// Ink (React)
<Box flexDirection="column">
<Text color="cyan">Count: {count}</Text>
</Box>
// Celestial (TSX)
<Box flexDirection="column">
<Text color={color.brightCyan}>Count: {model.count}</Text>
</Box>
Compiling to Single Binary
Package your app into a single native executable with zero external Node runtime required on the user's machine.
# Using Node.js 20+ Single Executable Application
node scripts/bundle-sea.mjs src/index.ts my-cli
# Output: dist-bin/my-cli.exe (Windows) or dist-bin/my-cli (Linux/macOS)