Early Beta · v0.0.0
Node-first · Rust-powered

Terminal UIs that don't
fight your runtime

BetterTUI wraps a memory-safe Rust engine in a thin TypeScript API. Build terminal interfaces with React or SolidJS — no garbage collection pauses, no memory leaks, no bundle bloat. Designed for Node.js first, Bun compatible.

$npm install @bettertui/core
Node.js ≥ 24Bun compatible🦀 Rust engine
app.tsx@bettertui/react
import { Box, Text, useInput } from "@bettertui/react";
import { render } from "@bettertui/core";

function App() {
  useInput((key) => { if (key === "q") process.exit(0); });

  return (
    <Box flexDirection="column" padding={1}>
      <Text bold color="green">● BetterTUI — Rust-powered TUI</Text>
      <Text dimColor>Node-first · Memory-safe · v0.0.0-beta</Text>
    </Box>
  );
}

render(<App />);

Runtime & Framework Support

Node.js ≥ 24Primary
BunCompatible
First-class adapters
React 19first-class
SolidJSfirst-class

Vue · Svelte · Preact · and more — planned for future releases

Features

Everything you need. Nothing you don't.

Built from first principles — not as a feature list, but as a coherent set of technical decisions.

Rust-Backed Engine

Layout and ANSI rendering run natively in a Rust .node addon. No JavaScript on the hot render path. No garbage collection pauses mid-frame.

Node.js First

Designed for Node.js ≥ 24 with stability as the first priority. Bun compatible when you need it — no runtime surprises, no polyfills.

React & SolidJS First-Class

Proper reconciler adapters for React 19 and SolidJS — not thin wrappers, not adapters bolted on. Framework primitives map directly to the engine.

Memory-Safe Rendering

The Rust engine uses arena allocation with generational indices. Memory leaks in the render pipeline are impossible by construction.

Rust guarantee

Minimal JS Bundle

The heavy lifting lives in the native addon — entirely outside your JS bundle. The TypeScript layer is deliberately thin and tree-shakeable.

TypeScript Throughout

Complete type inference from JSX props to the native bridge. No `any`, no guessing. Autocomplete and compile-time safety everywhere.

How it works

Familiar patterns. Native speed.

Write components exactly like you would for the web. BetterTUI translates them to the terminal through its Rust engine.

app.tsx
import { Box, Text, useInput } from "@bettertui/react";
import { render } from "@bettertui/core";

function App() {
  useInput((key) => {
    if (key === "q") process.exit(0);
  });

  return (
    <Box flexDirection="column" padding={1}>
      <Text bold color="green">Count: {count}</Text>
      <Text dimColor>Press q to quit</Text>
    </Box>
  );
}

render(<App />);

Terminal output

my-app
● Count: 0
Press q to quit

See it in action

From install to running in minutes

The Rust engine initialises on first import. No configuration. No build step.

terminal
~/my-app
$ npm install @bettertui/core @bettertui/react
✓ Added 2 packages
$ node --loader ts-node/esm app.tsx
✓ Rust engine loaded (native .node addon)
✓ Reconciler ready
BetterTUI DashboardPress Tab to navigate
CPU
████████░░81%
Memory
████░░░░░░42%
Rust engine
█░░░░░░░░░~0ms garbage collection
Press q to quit

How It Works

Built different from the ground up

A memory-safe Rust engine underneath a TypeScript-first API. Every layer has a single responsibility.

01

Layer 1

Framework Adapters

@bettertui/react
@bettertui/solid

React 19 + SolidJS · First-class reconcilers

02

Layer 2

@bettertui/core

TypeScript

CommandBuffer · Runtime · Tree Reconciliation

A thin, intentional TypeScript layer. Orchestrates the bridge between your framework and the native engine.

100%type-safefrom JSX props to native bridge
03

Layer 3

Rust Engine

🦀 Rust · Native Node Addon

Taffy Layout · ANSI Renderer · Arena Allocator

The hot render path runs natively. No garbage collector pressure. Arena allocation with generational indices means no memory leaks possible.

Zero garbage collection pausesArena allocationTaffy flexbox
10–50×faster renderingvs pure-JS equivalent

Why BetterTUI

Stability is the feature nobody ships

Built from the ground up on memory-safe Rust — because existing tools made the wrong tradeoffs, and production TUIs deserve better.

The Origin

BetterTUI was born from direct experience with OpenTUI — an impressive library that proved the TypeScript ecosystem deserves a first-class TUI framework. But using it in real applications revealed two hard constraints: a Bun runtime requirement and a Zig-backed terminal layer. Both are remarkable engineering achievements. Neither is a foundation you'd build production software on when stability is non-negotiable — Bun is still experimental with known compatibility gaps, and Zig's memory model brings hazards that compound under real workloads.

That raised a single question: what if we built this right, from scratch, on the most memory-safe foundation available? The answer is Rust — not as a trend, but as the only language where memory leaks and data races are impossible by construction.

Runtime

Bun — experimental

Node.js ≥ 24 — stable

System Layer

Zig — memory hazards

Rust — safe by design

Memory Model

GC pauses mid-frame

Arena allocation, no GC

Runtime Instability

Bun is fast but experimental — unpredictable behavior, incomplete Node.js compatibility, and sharp production edges. Zig-backed terminals carry known memory hazards that surface under load.

Our solution

Node.js ≥ 24 as the primary target. The Rust engine eliminates memory hazards by construction — no manual allocations, no use-after-free, no runtime surprises.

Garbage Collection Pauses

Pure-JS TUI renderers compete with your app for the garbage collector. A 50ms GC pause in a real-time dashboard is visible and jarring.

Our solution

The Rust engine never touches the JS heap. Layout and rendering are garbage collection–free by construction.

Bundle Bloat

Traditional TUI libs ship the full rendering engine in JS — parsing, layout, ANSI encoding. That's hundreds of kB in your bundle.

Our solution

The JS layer is a thin orchestration bridge. All the heavy work lives in the native addon — entirely outside your bundle.

Framework Lock-in

Ink is React-only. Blessed has no modern framework adapters. You either fight your framework or give up features.

Our solution

First-class adapters for React 19 and SolidJS. Same Rust engine, same API, different reconciler.

OpenTUI as the benchmark

Every feature BetterTUI ships is validated against OpenTUI's complete example suite. If OpenTUI can demonstrate it, BetterTUI must match or exceed it on a stable, memory-safe foundation. Their examples are our acceptance criteria and our definition of done.

Standing on the shoulders of giants

A sincere thank you to every contributor who built OpenTUI. Your work demonstrated what was possible in the TypeScript ecosystem, gave us our benchmark, and motivated building something the entire community can rely on. This project exists because of your effort.

⚠ Early Beta — v0.0.0

BetterTUI is not production-ready. The API is unstable and actively evolving. We're sharing early to collect feedback from the community.

Early Beta — not production-ready

Help shape what BetterTUI becomes

We're in early beta and actively refining the API with early adopters. Star the repo, try it out, and tell us what's broken.

Apache 2.0 licensed · Built in public on GitHub