A dependency-free TypeScript terminal UI runtime. Screens are plain data; JSX is one way to write them.
npm install textui @textui/widgetsimport { render } from 'textui';
import { registerBuiltins } from '@textui/widgets';
const { waitUntilExit } = render(<Dashboard />, { onBoot: registerBuiltins });
await waitUntilExit();Status: pre-1.0. The surface is still moving.
JSX compiles to data. <Row gap={1}/> and { component: 'Row', gap: 1 } are the same value, and the runtime mounts either. A screen can be written in TypeScript, loaded from JSON, generated, edited or sent over a wire without the runtime changing - and components are resolved by name at mount time, so what renders is a registration rather than an import.
Everything else follows from that: one reactive store addressed by paths, typed registries for components, commands, themes, shells and resources, and a renderer that diffs cells rather than redrawing frames.
Nothing is installed alongside it. @textui/core has an empty dependencies,
and the packages above it depend only on each other - so what you audit is what
you get, and the tree does not grow behind your back.
That also keeps the source close to running unbuilt: Node has erased types by
default since 23.6, and most of this codebase is already erasable syntax. The
full argument, and what is still in the way, is in
DEVELOPER.md.
| Package | What it is |
|---|---|
textui |
One install: the runtime, a terminal, and render. Start here |
@textui/core |
The runtime: store, registries, renderer, hooks, the four host primitives |
@textui/widgets |
The component catalog: layout, display, controls, data, overlays, charts |
@textui/terminal |
Terminal adapters, capability detection, ANSI writing, input decoding |
@textui/testing |
Headless harness: semantic queries, input, resizing, time |
@textui/cli |
textui init / add / create / doctor, and primitives for your own CLI |
Also in the repository, not yet published:
| Package | What it is |
|---|---|
@textui/documents |
Document buffers, resource viewers and content adapters |
@textui/textide |
An IDE that runs in a terminal, built on TextUI |
@textui/textide-git |
Git for textide, as a loadable extension |
components/ |
The source-copy registry - components you own, not import |
playground/ |
The showcase, fourteen focused playgrounds, and a filesystem explorer |
Published at https://softov.github.io/textui/, and readable in docs/ as plain markdown.
Start here:
| Document | What it answers |
|---|---|
| Getting started | From nothing to a running application |
| The vocabulary | The words everything else assumes |
| Architecture | The model: store, graph, registries, surfaces, shells |
| Decisions and tradeoffs | What was chosen, and what it cost |
Then by subsystem:
| Section | What it covers |
|---|---|
| Store | Paths, scopes, computed, collections, providers, events |
| Components | The catalog, how to write one, and the templates |
| Themes | Tokens, glyphs, borders, capability downgrade, syntax |
| Platform | Commands, keybindings, focus, layers, screens, extension points |
| Terminal | Adapters, capabilities, managed and embedded sessions |
| Documents | Resource kinds, providers, viewers, editors, buffers |
| CLI | The developer CLI and the registry model |
| Testing | The harness, and what to assert |
Let's cut to the chase, shall we?
Here's what TextUI actually looks like and what it can do.
Working on TextUI rather than with it - building, testing, the playgrounds, the
docs site and how a release is cut - is in DEVELOPER.md.
MIT