justerm-core
A pure terminal engine in Rust — the core crate of the justerm
family. Feed it a VT byte stream; it owns the terminal state (grid + scrollback + cursor + selection)
and emits a viewport snapshot, damage, scroll ops, and extractable text. It is not a renderer and
not a full emulator.
- No I/O — the caller feeds bytes (
feed(&[u8])); justerm-core never touches a PTY/SSH/socket. - No IPC — it provides a binary format, not transport.
- No rendering — a renderer draws (the family's first-party
justerm-renderer, WebGL2, replacing the third-partybeamterm). - Theme-agnostic — colours are references (Default / Indexed / RGB), never resolved hex; the consumer resolves them.
Install
Usage
Feed VT bytes in, read terminal state out — no PTY, no rendering, no theme:
use ;
// An 80×24 viewport. The caller owns I/O; justerm-core only parses bytes.
let mut term = new;
// A VT stream: "hi" in SGR red (ESC[31m … ESC[0m).
term.feed;
// Read the grid back: the character, and the colour *reference*
// (Indexed(1) = ANSI red — resolving it to a hex value is the consumer's job).
assert_eq!;
assert_eq!;
Engine also exposes damage() (the line + column ranges changed since the last read),
viewport_line() / viewport_logical_lines(), resize(), and a binary wire format
(serialize) for shipping frames to a consumer with no TypeScript mirror to drift.
Status: in active use. The core engine is implemented and consumed across the family (
justerm-wasm-decode,justerm-web,justerm-renderer). VT compliance is cumulative — the common cases are covered and the long tail grows as dogfooding surfaces it. See the issue tracker for the current frontier. First consumer: PenTerm (a Tauri terminal app).
Docs
CLAUDE.md— identity, boundary invariants, conventions, working method.CONTEXT.md— glossary.docs/architecture.md— the contract: cell, damage, viewport/scroll, cadence, selection, serialization, engine API — plus a Hidden VT state checklist (with where to look in reference impls) for implementers.docs/adr/— key decisions (build onvte, notalacritty_terminal; adopt then replacebeamtermwith the first-partyjusterm-renderer, ADR-0002 → ADR-0018).
Web consumers
The wire format's decoder is shipped to the web as justerm-wasm-decode — the
native decode compiled to WASM and published to npm, version-locked to this crate, so the backend
encoder and the webview decoder share one implementation (no TypeScript mirror to drift). It decodes
into structure-of-arrays cell columns and ships the format-owned helpers (resolveRgb /
buildPalette / flags); the theme values (your palette) and render policy (atlas, cursor) stay
the consumer's adapter. See justerm-wasm-decode/README.md and
ADR-0008.
License
Licensed under either of
- Apache License, Version 2.0 (
LICENSE-APACHE) - MIT license (
LICENSE-MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.