libghostty-vt-node
v0.1.0
Published
Node.js bindings for libghostty-vt (Ghostty's terminal emulation library) via WebAssembly. No native compilation, works on every platform Node supports.
Maintainers
Readme
libghostty-vt-node
Node.js bindings for libghostty-vt, Ghostty's terminal emulation library: feed it terminal output (the raw bytes a program writes to a pty) and read back what a terminal would display — plain text, styled HTML, or replayable VT sequences — plus terminal state like cursor position, title, and scrollback.
It is a state engine, not a renderer: no screenshots, no GUI.
Inspired by coder/libghostty-vt-node, rebuilt for simple maintenance (see Design below).
Usage
import { Terminal } from "libghostty-vt-node";
using term = new Terminal({ cols: 80, rows: 24 });
term.feed("ls --color\r\n\x1b[1;34msrc\x1b[0m \x1b[1;34mtest\x1b[0m README.md\r\n");
term.text(); // plain text of the screen (scrollback included)
term.html(); // HTML with inline styles
term.vt(); // VT escape sequences that replay colors/styles
term.cursor; // { x, y, visible }
term.title; // window title from OSC 0/2, "" if unset
term.activeScreen; // "primary" | "alternate"
term.scrollbackRows; // rows currently in scrollback
term.resize(120, 40); // reflows the primary screen
term.reset(); // full reset (RIS)Terminals hold memory inside the WebAssembly instance, so free them when
done: either declare them with using (as above; the syntax needs
Node 24+) or call term.dispose().
API
new Terminal(options?)—cols(80),rows(24),scrollbackMaxBytes(0disables scrollback),scrollbackMaxLines.feed(data)— write program output; acceptsstring(encoded as UTF-8) orUint8Array. Malformed input never throws; libghostty treats the stream as untrusted.text(options?)/html(options?)/vt(options?)— format the screen contents including scrollback. Options:trim(defaulttrue, trims trailing whitespace),unwrap(defaultfalse, joins soft-wrapped lines).resize(cols, rows),reset(),dispose().- Getters:
cols,rows,cursor,title,pwd,activeScreen,scrollbackRows,totalRows,isDisposed. libghosttyVersion()— version of the bundled libghostty-vt.
Errors from the library throw LibGhosttyVtError with a code such as
"OUT_OF_MEMORY".
Design
The goal of this package is to stay maintainable by keeping the moving parts to a minimum:
- WebAssembly, not a native addon. Upstream Ghostty officially supports
building libghostty-vt for
wasm32-freestanding(it has no dependencies, not even libc). One ~700 KB.wasmfile runs on every platform and architecture Node supports — no node-gyp, no C++ glue, no per-platform prebuilds, no binary release matrix. - The wasm artifact is committed.
wasm/ghostty-vt.wasmis built from the upstream commit pinned inwasm/UPSTREAM.json. Contributors and consumers never need Zig; it is only required when updating the bundled library (npm run build:wasm). - No hardcoded ABI. Struct layouts, field offsets, and enum values are
read at load time from the module's own ABI manifest
(
ghostty_type_json()), which upstream provides exactly for bindings like this. Layout changes upstream are absorbed automatically. - Zero runtime dependencies. The wrapper is two TypeScript files
(
src/module.tsfor wasm plumbing,src/index.tsfor the public API), tested withnode:test.
Updating the bundled libghostty-vt
GHOSTTY_REF=<upstream-commit> npm run build:wasm # needs Zig (see wasm/UPSTREAM.json)
npm testThe script pins the new commit in wasm/UPSTREAM.json; commit both files.
Development
npm install # dev tooling only (typescript)
npm test # runs tests directly on the TypeScript source
npm run build # emits dist/ for publishingRequires Node >= 22.18 (tests run TypeScript via Node's built-in type stripping).
Scope
The API is intentionally small: feed bytes, inspect state, extract
formatted output. The underlying wasm module exports much more of
libghostty-vt (grid refs for per-cell inspection, key/mouse encoding,
selections, snapshots, render state) — the loader in src/module.ts
already provides everything needed to bind more of it if a use case shows
up. Note that upstream marks the C API as unstable and evolving.
License
MIT. Ghostty and libghostty-vt are © Mitchell Hashimoto and the Ghostty contributors, also MIT-licensed.
