Rust / Node.js / TypeScript / TSX

The terminal is a surface, not a side effect.

Slate gives terminal interfaces a real runtime: layout, input, focus, media and cleanup with contracts you can read before the process owns the screen.

No React requiredNative input is optionalApache-2.0

slate / runtime-preview READY

$ slate.session--explicit

rendererANSI
inputmouse
statesignal

tree resolved / IDs stable

frame committed / output deduped

cleanup armed / Ctrl+C reserved

$npm install @slate-terminal/core @slate-terminal/react
const app = render(view, { viewport: { width: 80, height: 24 } });
process.stdout.write(app.renderAnsi());
app.close();
2.3.0current release
Node 18+runtime baseline
Rust + N-APInative where it matters
Apache-2.0open source license

01 / Choose the boundary

Start small. Open the terminal only when you mean to.

render / return

One frame, no session

For snapshots, generated output, tests and tools that should render ANSI and exit without raw mode or native input.

import { Container, Text, render } from "@slate-terminal/react";

const app = render(Container({
  id: "app",
  children: Text({ id: "hello", text: "Hello, Slate" })
}));

process.stdout.write(app.renderAnsi());
app.close();
native addon: optionalsee the contract ↗
session / own

Live terminal session

For keyboard, mouse, paste, resize and focus. The session opens modes; the controller polls, presents and closes them.

const session = createTerminalSession();
const terminal = createTerminalController(
  app, session.input, createSlateOutput(process.stdout)
);

terminal.start();
// Ctrl+C or your action can close it.
terminal.close();
native addon: requiredopen live guide ↗

02 / The system

A terminal UI with the parts people actually notice.

01LayoutFlexbox, clipping, wrapping and stable IDs.
02InputKeyboard, mouse, paste, resize and normalized events.
03StateSignals, widgets, focus managers and controlled updates.
04ExitCursor, modes, listeners and native resources restored.
surface / 01Layout
button / 02Input
dock / 03Focus
mosaic / 04Media

The expressive layer borrows the useful part of M3 — semantic color, contrasting shapes and stateful motion — then maps it honestly onto terminal cells, ANSI color and real input.

03 / Built for agents

Readable contracts beat clever guesses.

Slate tells an agent which API owns input, which one only renders, when native is required and what cleanup means. Less archaeology. Fewer defensive typeof branches.

render()Builds the application tree. Does not start polling.
renderAnsi()Returns one frame. Does not own the terminal.
start()Connects input, commits output and installs lifecycle handling.
close()Stops work, restores resources and is safe to call again.
nativeOptional for rendering; required for physical terminal modes.

Go where the work is.

The landing page tells you what Slate owns. The docs show how to use it without guessing.