Skip to content

CLI Reference

The @termless/cli package is a command-line tool built around the four recording-domain verbsrecord, view, play, compare — plus the config and diagnostic surfaces backends, doctor, themes, and the mcp server.

For the MCP server tool list, see the MCP Reference.

Installation

bash
npm install @termless/cli
bash
bun add @termless/cli
bash
pnpm add @termless/cli
bash
yarn add @termless/cli

Or run directly:

bash
$ bunx termless record -o demo.gif -- bun km view ~/Vault

termless record

Capture a terminal session into a Recording and write it to one or more output files. Alias: termless rec.

record has exactly one output flag — -o. The shape of each -o value picks the mode; there is no separate format flag and no separate screenshot flag.

InvocationOutput
termless record -- <cmd> (no -o)out.gif — a single file in the cwd
termless record -o demos/ -- <cmd>demos/ folder — out.rec · out.gif · out.cast · out.tape
termless record -o a.gif -o b.castexactly a.gif + b.cast (-o is repeatable)
termless record -o shot.png -- <cmd>a single still PNG
termless record (no command)shows a help gate, then records a live $SHELL on Enter

The -o extension picks the format; the format decides whether a renderer is involved:

ExtensionFormatRenderer
.gif .apngraster animationthe renderer — auto (see below)
.pngraster stillthe renderer — auto (see below)
.svgvector still/animationnone (vector)
.htmlscrubbable browser viewernone server-side
.rec .tape .castrecording datanone

Renderers

A renderer rasterizes captured frames into pixels. --renderer picks one; the default is auto.

RendererHow it worksUse it for
swashRenders the cell grid directly (no SVG) via the pure-Rust swash crate — composites full-colour emoji from their native colour tables. Bundled font chain: JetBrains Mono + Noto Sans Symbols 2 + Symbols Nerd Font + Noto Emoji.The default — highest fidelity.
resvgRenders each frame's SVG via @resvg/resvg-js, handed the same bundled fonts. Clean glyph coverage; no native build.Cross-platform fallback.
canvasRasterizes the SVG through @napi-rs/canvas. Its drawImage path ignores registered fonts, so some glyphs tofu.Niche; prefer resvg.
browserRasterizes each frame's SVG in headless Chromium (Playwright) — a real browser text engine for Chrome-identical shaping, font fallback, ligatures, and colour emoji. Absolute-max fidelity.Premium opt-in: marketing assets + a fidelity oracle against swash/canvas.
autoResolves to swash, falling back to resvg then canvas. Never browser.The default.

auto prefers swash — it consumes the cell grid directly, so colour emoji, Nerd Font icons and box-drawing all render faithfully. Where the swash native binding is unavailable it falls back to resvg, which renders the SVG path with the same bundled fonts.

browser — the premium opt-in tier

browser is the highest-fidelity renderer: it hosts each frame's SVG in a headless-Chromium page and screenshots it, so output matches Chrome exactly (shaping, fallback, ligatures, colour emoji). It is opt-in only and never chosen by auto — Chromium is a hundreds-of-MB dependency, too heavy for a default or CI. Reach for it for one-off README/blog assets, or as a correctness oracle (render the same frame via browser and swash, diff them).

Playwright is an optional dependency — a default bun install omits it and swash/resvg/canvas are unaffected. Install it before using --renderer browser:

bash
bun add -d playwright
npx playwright install chromium

Without playwright, --renderer browser fails fast with that exact install hint.

bash
# Bare record — shows a help gate, then records a live $SHELL on Enter
$ termless record

# Record a command — no -o → out.gif in the cwd
$ termless record -- bun km view ~/Vault

# Folder bundle — a trailing slash writes out.{rec,gif,cast,tape}
$ termless record -o demos/ -- bun km view ~/Vault

# Named files — -o is repeatable; the extension picks the format
$ termless record -o demo.gif -o demo.cast -- bun km view ~/Vault

# A single still PNG
$ termless record -o shot.png -- bun km view ~/Vault

# Force the resvg renderer (the common case never touches --renderer)
$ termless record --renderer resvg -o demo.gif -- bun km view ~/Vault

# Compat capture: record in a real desktop terminal app (macOS)
$ termless record --compat -o c.png -- bun km view ~/Vault

Options

OptionDescriptionDefault
-o, --output <path...>Output path — extension picks the format, trailing / a folder bundle (repeatable)out.gif
--renderer <kind>Raster renderer: resvg, swash, canvas, browser, or autoauto
-t, --tape <commands>Inline tape commands (scripted mode)--
-b, --backend <name>Backend for scripted modevterm
--cols <n>Terminal columns80
--rows <n>Terminal rows30
--timeout <ms>Wait timeout in ms5000
--keys <keys>Comma-separated key names to press, then capture a still--
--wait-for <text>Wait for text before pressing keyscontent
--textPrint terminal text to stdoutoff
--chrome <style>Window chrome on rendered output: none, macos, windowsnone
--title <text>Title text in the window chrome barthe command
--compatCompat capture — record in a real desktop terminal appoff
--terminal <name>Compat terminal app: ghostty, kitty, iterm, terminalauto-detect
--cwd <path>Working directory for the recorded command (with --compat)--

record's defaults are tuned for a README-droppable artifact: the ghostty backend (truecolor + real glyph shaping), 80×30 (GitHub renders README images at ~880px content width), ~12 fps, and a ~300-frame cap so a long session never produces a 50 MB GIF. Power users override every default.

Window chrome

--chrome wraps the rendered output in a window frame — the finishing touch for a README or blog image. It composites uniformly across PNG, SVG, and GIF output (the frame is baked into every captured frame).

StyleLook
noneNo chrome — the bare terminal grid (default; byte-identical to omitting the flag)
macosRounded top corners, three traffic-light dots, a soft drop shadow, a small margin
windowsA flat title bar with minimize / maximize / close glyphs

The bar background is derived from the terminal theme (a touch lighter on dark themes, darker on light ones). --title sets the bar's title text; it defaults to the recorded command. The macOS preset centers the title, the Windows preset left-aligns it.

bash
# A framed GIF, ready to drop into a README
$ termless record --chrome macos -o demo.gif -- bun km view ~/Vault

# A Windows-style framed still, with a custom title
$ termless record --chrome windows --title "km — Knowledge Machine" \
    --keys "j,j,Enter" -o shot.png -- bun km view ~/Vault

Compat capture (macOS)

termless record --compat records against the peekaboo backend — it spawns the user's real desktop terminal app (Ghostty / kitty / iTerm / Terminal.app), runs the command after --, screenshots the window, and cleans up. Pixel-perfect for that terminal plus the user's font and theme.

bash
$ termless record --compat -- bun km view ~/Vault
$ termless record --compat --terminal ghostty --cols 140 --rows 40 -o c.png -- bun km

Compat capture is macOS-only and needs a GUI session plus Screen Recording permission. For routine visual iteration use plain record (the resvg renderer) — the compat path is slow and pops a real window.

See Recording Sessions for detailed usage.

termless view

Present a recording — a single .rec file or a bare frame-trace directory. By default view writes a self-contained, scrubbable viewer.html alongside the recording; with --format gif it animates the recording's frames into a GIF.

bash
# Scrub a recording in the browser (writes viewer.html next to it)
$ termless view ./mysession.rec

# Animate a recording to a GIF
$ termless view ./trace --format gif -o demo.gif

Options

OptionDescriptionDefault
-o, --output <path>Output file for --format--
--format <type>Animate the recording to a file: gifscrub

Writing a GIF is not a separate "export" command — it is view with an animation format and a file sink. See Tracing Visual Bugs for the scrubbable viewer.

termless play

Re-execute a recording into a terminal. Accepts any recording format. Produce terminal text, screenshots, or animated output.

bash
# Play a recording (prints terminal text)
$ termless play demo.tape
$ termless play demo.cast

# Generate an animated GIF
$ termless play -o demo.gif demo.tape

# Generate an animated SVG
$ termless play -o demo.svg demo.tape

Options

OptionDescriptionDefault
-o, --output <path>Output file, format detected from extension--
-b, --backend <name>Backend(s), comma-separated; use all for every ready backendvterm
--compare <mode>Comparison mode — a thin alias for termless compare--
--cols <n>Override terminal columns--
--rows <n>Override terminal rows--

termless compare

Play one recording across two or more backends and diff the results — "does my TUI look the same in every terminal?" compare shares its execution core with play; play --compare <mode> is a thin alias for it.

bash
# Side-by-side comparison
$ termless compare demo.tape -b vterm,ghostty --compare side-by-side -o comparison.svg

# Compare every installed, ready backend
$ termless compare demo.tape -b all --compare grid -o all-backends.svg

# Diff mode — pixel-diff overlays against the baseline backend
$ termless compare demo.tape -b vterm,ghostty --compare diff -o diff.svg

Options

OptionDescriptionDefault
-b, --backend <name>Backend(s), comma-separated; use all for every ready backendvterm
--compare <mode>separate, side-by-side, grid, diff--
-o, --output <path>Output file or directory--

See Recording Sessions for the comparison modes.

Backend Management

Manage backend installation with Playwright-inspired commands. Backend versions are pinned in backends.json — upgrading termless upgrades all backends together.

termless backends

List all available backends with their type, install status, and version. termless backends list is the same command.

bash
$ termless backends
$ termless backends list

termless backends install

Install backends. With no arguments, installs the default set (xtermjs, ghostty, vt100).

bash
$ termless backends install
$ termless backends install ghostty
$ termless backends install ghostty alacritty

termless backends update

Check upstream registries (npm, crates.io, GitHub) for newer backend versions, compared against the versions pinned in backends.json.

bash
$ termless backends update           # dry run
$ termless backends update --apply   # apply to backends.json

termless doctor

Check installation health: verify installed backends load correctly, detect version mismatches, and report missing dependencies.

bash
$ termless doctor

termless themes

List the color themes available for recording screenshots and animations.

bash
$ termless themes

Use a theme with termless play --theme dracula demo.tape, or Set Theme "dracula" inside a .tape file.

termless mcp

Start a stdio MCP server for AI agents (Claude Code, etc.).

bash
$ termless mcp

The full tool list and Claude Code integration are documented in the MCP Reference.

Session Manager (Programmatic)

The session manager is also available as a library:

typescript
import { createSessionManager } from "@termless/cli"

const manager = createSessionManager()

const { id, terminal } = await manager.createSession({
  command: ["my-app"],
  cols: 120,
  rows: 40,
  waitFor: "ready>",
  timeout: 5000,
})

terminal.press("ArrowDown")
await terminal.waitForStable()
console.log(terminal.getText())

await manager.stopSession(id)
// or: await manager.stopAll()

createSession(options?)

OptionTypeDefaultDescription
commandstring[]--Command to spawn
envRecord<string, string>--Additional env vars
cwdstring--Working directory
colsnumber120Terminal columns
rowsnumber40Terminal rows
waitForstring | "content" | "stable""content"What to wait for after spawn
timeoutnumber5000Wait timeout in ms

getSession(id)

Get a Terminal instance by session ID. Throws if not found.

listSessions()

Returns an array of { id, command, cols, rows, alive } for all sessions.

stopSession(id) / stopAll()

Close the terminal and kill the process for one or all sessions.

Key Names

Keys use the same format as terminal.press():

  • Single characters: a, 1, /
  • Named keys: Enter, Tab, Backspace, Delete, Escape, Space
  • Arrow keys: ArrowUp, ArrowDown, ArrowLeft, ArrowRight
  • Navigation: Home, End, PageUp, PageDown
  • Function keys: F1 through F12
  • With modifiers: Ctrl+c, Shift+Tab, Alt+x