
LeTUI
TUI library built from scratch with TypeScript and a Rust core, featuring a component-based API, signal-based state management, CSS-like styling API, a Rust-powered layout and rendering engine, and cell-based diffing.


TUI library built from scratch with TypeScript and a Rust core, featuring a component-based API, signal-based state management, CSS-like styling API, a Rust-powered layout and rendering engine, and cell-based diffing.
original
anime4kIn-browser MKV video streamer and player built from scratch, featuring real-time 4K anime upscaling powered by WGSL (WebGPU) shaders ported from Anime4K.

Web app and CLI for exporting X threads, articles, posts, and replies as Markdown or JSON, built around resumable jobs.
Paid music collaborations and song-cover campaigns for artists worldwide. Led frontend and backend development across both products, built the Next.js frontend from scratch, and owned payments, payouts, and mobile audio features. Cut data processing for 1M+ artists from nine days to seven hours and roughly halved Soundcharts costs.
AI mapping platform for satellite and aerial imagery. Built high-performance React interfaces for large imagery datasets, simplified component state and data flow, and helped move users to centralized sign-in with zero downtime.
Social content and analytics platform with shoppable feeds for brands. Led React adoption within an Angular application and improved embedded app performance for e-commerce sites across Europe. Built a custom state manager that cut the JavaScript bundle by 20% and automated package publishing.
Online clothing brand. Fully automated stock updates with a tested pipeline that transformed Airtable inventory data and stored it in the website's database.
Online sports insurance company for individuals, tournaments, etc. Built payment and subscription workflows and internal support tools, redesigned the PostgreSQL schema, and consolidated two backends into one codebase.
TUI library with a Rust rendering core and TypeScript wrapper API. Written from scratch.
The AI agent demo is a functional Amp-inspired coding agent built entirely with LeTUI. It uses the Codex app-server for ChatGPT subscription authentication and agent execution, and keeps its own thread index, transcript, archive state, and cross-thread references in local SQLite.
# Requires the Codex CLI on PATH. Sign-in can be completed from the command palette.
bun run ai-agentPress Ctrl+O for commands, Ctrl+S to cycle reasoning effort, Alt+T to expand tool details,
@ to mention files, or @@ to reference a previous local thread. The footer reports the Codex
five-hour subscription window instead of API cost or credit data.
darwin-arm64, linux-x64, win32-x64git clone https://github.com/frixaco/letui.git
cd letui
bun install
bun run build-ffiMore examples:
bun run examples/typing-speed.ts(bun run anitrack is for personal testing and requires mpv player configured with Anime4K shaders)
Checks:
bun run typecheck
bun run check:rustbun add @frixaco/letuiOn supported targets, install pulls the matching native binary automatically.
Minimal reactive app:
import { $, Column, Text, appearance, ff, onKey, run } from "@frixaco/letui";
const THEME = {
fg: 0xf5f7fa,
muted: 0x94a0b2,
surface: 0x16181a,
border: 0x3c4048,
} as const;
const count = $(0);
const counterText = Text({
text: "count: 0",
foreground: THEME.fg,
});
ff(() => {
counterText.setText(`count: ${count()}`);
});
const root = Column(
{
flexGrow: 1,
gap: 1,
padding: "1 1",
background: THEME.surface,
border: { color: THEME.border, style: "rounded" },
},
[
Text({ text: "hello from letui", foreground: THEME.fg }),
counterText,
Text({
text: "+ / - update, q quit, Ctrl+Q default quit",
foreground: THEME.muted,
}),
],
);
ff(() => {
const mode = appearance();
root.setStyle({
background: mode === "light" ? 0xffffff : THEME.surface,
});
});
const app = run(root);
onKey("+", () => count(count() + 1));
onKey("-", () => count(count() - 1));
onKey("q", () => app.quit());bun run app.tsframe / frameWidth() / frameHeight(), while Rust also exposes the final visible hitmap for interactiondarwin-arm64, linux-x64, win32-x64crossterm, taffy, unicode-width, and unicode-segmentation.Text wrapping, clipping, and overflow are resolved in the Rust renderer. Explicit newlines are treated as hard row boundaries after text normalization.
Vertical scrolling is available on ScrollView:
const viewport = ScrollView(
{
flexGrow: 1,
minHeight: 0,
scrollY: 12,
},
[content],
);ScrollView always scrolls vertically. scrollY is a row offset; Rust clamps oversized values, floors fractional values to whole rows, and owns the final hit-testing for the visible scrolled region.
Debug metrics split the frame into js, render, sync, and flush, plus a worst-frame breakdown. Enable with run(root, { debug: true }) to print the summary on quit. If you also want a file, pass run(root, { debug: true, metricsPath: "dump/metrics.txt" }).
Appearance detection requests the current terminal color scheme at startup and listens for live theme updates on terminals that support DEC 2031. Startup detection asks for DEC color-scheme status first and also sends an OSC 11 background-color query as a fallback. appearance() returns "light", "dark", or "unknown".
import { Column, Text, appearance, ff, onKey, run } from "@frixaco/letui";
const label = Text({ text: "theme: unknown" });
const root = Column({ flexGrow: 1, padding: "1 1" }, [label]);
ff(() => {
const mode = appearance();
label.setText(`theme: ${mode}`);
root.setStyle({
background: mode === "light" ? 0xf6f6f6 : 0x101215,
});
label.setStyle({
foreground: mode === "light" ? 0x111111 : 0xf5f7fa,
});
});
const app = run(root, { appearance: "auto" });
onKey("q", () => app.quit());Pass appearance: "light", "dark", or "unknown" to run() to override detection.
Generally speaking it's on par if not faster than OpenTUI, Ink and probably any other popular TUI library at its current state. It loses to Ratatui though, as it is pure Rust.
StyledText spansScrollViewtop/left insets, explicit layer ordering, overlay hosts, and modal focus containmentflush with BatchWriter patternSee docs/releasing.md.