// ZTERMINAL — ENGINEERING REPORT

GPU-accelerated cross-platform terminal in Rust · OpenGL ES 2.0 glyph-atlas renderer · xterm-compatible VT engine · native tiling splits · inline graphics (Kitty / Sixel / iTerm2) · first-class tmux over the native wire protocol

Docs
// Color scheme

>_EXECUTIVE SUMMARY

zterminal is a fast, GPU-accelerated terminal emulator written in Rust, organized as a 5-crate workspace. A terminal engine (zterminal_core) owns the xterm-compatible VT parser, the grid and scrollback, inline-graphics state, and PTY I/O; the application shell (zterminal) owns the OpenGL ES 2.0 glyph-atlas renderer, window/display driver, the native binary-split pane tree, input and keybindings, and a configuration model bridged to an in-process WebView control panel. tmux integration rides on a dedicated wire-protocol client (ztmux-core) that speaks imsg framing directly to the server socket — no tmux subprocess. Configuration is deserialized through a custom derive crate (zterminal_config_derive). ~60k Rust source lines across 118 files + ~6.8k lines of control-panel JavaScript + 626 test functions, in a vendored, self-contained build with no external runtime dependencies, targeting Linux, BSD, macOS, and Windows.

59,947
Rust Source Lines
44,844
Code Lines (tokei)
113
Rust Files
5
Workspace Crates
600
Test Functions
6,481
Control-Panel JS Lines
41
Direct Dependencies
535
Crates In Tree
3
Inline-Image Protocols

Crate Distribution — 59,947 Rust lines

39,871 zterminal / 18,264 zterminal_core / 1,208 zterminal-ledger / 604 config · 66.5% app shell

zterminal (71 files) — renderer, display, input, splits, config, platform. zterminal_core (34 files) — VT engine, grid, graphics, PTY, vi mode, selection. crates/zterminal-ledger (2 files) — the command-block ledger behind retroactive diff / trend / sort / JOIN. zterminal_config + zterminal_config_derive (6 files) — config deserialization. crates/ztmux-core (5 files, 2,359 lines) — the tmux wire protocol; its own repo, consumed as a path dep and excluded from this workspace, so it is not counted above.


#SUBSYSTEM BREAKDOWN

Source partitioned by role across the workspace, measured in total source lines. The application shell’s event loop and configuration surface lead, followed closely by the VT engine, the GPU renderer, and the display/windowing driver. Percentages are of the 59,947-line Rust slice.

SubsystemKey pathsLines%ShareDescription
Config & settingsconfig/, settings.rs, migrate/8,19713.7%
Config schema (colors, window, opacity, background image), keybinding table, settings model + persistence, and migration of older configs. Bridged to the WebView control panel.
Event loop & app coreevent.rs, window_context.rs, pane.rs, main.rs, daemon.rs9,32115.5%
Central event dispatch (window / keyboard / mouse / IPC), per-window context (tabs, panes, focus, MRU), the native binary-split pane tree, app entry, and the background daemon.
Terminal / VT enginecore/term/5,5799.3%
The xterm-compatible VT parser and terminal state machine: escape / CSI / OSC handling, modes, cursor, charsets, tab stops, and in-scrollback regex search.
Display & windowingdisplay/5,6719.5%
Per-window draw orchestration, damage tracking, cursor and overlays, hint / hyperlink overlay, OS window creation and management.
GPU rendererrenderer/5,2178.7%
OpenGL ES 2.0 glyph-atlas renderer: text shaping into a texture atlas, GLES2 draw path, and an embedded fallback glyph font so the build is self-contained.
Automation & fleet waitsexpect.rs, quorum.rs, snapshot.rs, query_pane.rs, zbus.rs, filebrowser.rs4,6847.8%
Typed blocking waits on a live pane (expect), set-valued fleet waits decided by a policy (quorum), coherent query instants (snapshot), panes whose contents are a query, the GUI Automation Bus endpoint reaching zterminal as App::open("zterminal") from stryke, and the hosted multi-pane file browser
Retroactive output intelligencecore/query.rs, core/shell.rs, core/column.rs, core/diff.rs, core/metric.rs, ledger.rs, crates/zterminal-ledger/4,8598.1%
OSC 133 command-block capture and everything built on it: the durable command-block ledger that survives scrollback eviction, retroactive diff of a command against its previous run, numeric trend across runs, in-place column sort of printed output, and the cross-command relational JOIN over captured output.
Grid & scrollbackcore/grid/2,8224.7%
Cell storage, rows, resize / reflow, and the scrollback ring-buffer storage.
Utilitiescli.rs, message_bar.rs, logging.rs, string.rs, clipboard.rs, triggers.rs, scheduler.rs, recent_dirs.rs, panic.rs, core/event.rs, core/thread.rs, core/lib.rs2,8374.7%
CLI argument parsing, the on-screen message bar, structured logging, string helpers, clipboard integration, and assorted app glue (panic handler, recent dirs, scheduler, triggers, Windows support).
Input & keybindingsinput/2,5124.2%
Key / mouse → action mapping, modifier handling, keysym → escape-sequence encoding, bracketed paste.
Inline graphicscore/graphics/2,1893.7%
Image-placement state and GPU upload queue for inline graphics, plus the scanner that extracts Kitty (APC), Sixel (DCS), and iTerm2 (OSC) image sequences ahead of the escape parser.
PTY / TTYcore/tty/1,6012.7%
Pseudo-terminal spawn and I/O: child process, resize, and the read/write loop feeding the VT engine.
Core event loop & indexcore/event_loop.rs, index.rs, sync.rs1,0151.7%
The terminal engine’s event loop, grid coordinate / index types, shell helpers, and synchronization primitives shared with the shell.
vi modecore/vi_mode.rs8931.5%
vi-style cursor motions, selections, and operators over the grid and scrollback.
Selectioncore/selection.rs6871.1%
Selection model (block / semantic / line) and clipboard text extraction.
Config derive macroszterminal_config*/6041.0%
Procedural-macro config deserialization (struct / enum) and serde replace support, plus the thin config crate entry.
macOS platformmacos/6231.0%
macOS-specific glue: native menu, global hotkey (Quake dropdown), and app integration.
Pollingpolling/3990.7%
Periodic polling for telemetry / tmux refresh feeding the dashboard.
Windows platformwindows/2370.4%
Windows-specific glue: the native menu integration.
TOTAL59,947100%

$TOP 20 FILES BY SIZE

The 20 largest source files account for 58.2% of the Rust slice. The event loop and the terminal-state core are by far the largest single files — the two hubs that everything else hangs off.

FileLinesRole
zterminal/src/event.rs5,139Central event loop: window / keyboard / mouse / IPC event dispatch and the application state machine
zterminal_core/src/term/mod.rs3,944Terminal state: the VT / xterm parser core, grid mutation, modes, cursor, charsets
zterminal/src/settings.rs3,178Settings model and persistence, bridged to the WebView control panel
zterminal/src/window_context.rs2,790Per-window context: tabs, panes, focus, MRU quick-switch
zterminal/src/display/mod.rs2,007Display driver: per-window draw orchestration, damage, cursor, overlays
zterminal/src/input/mod.rs1,630Input handling: key / mouse → action mapping, modifiers, bracketed paste
zterminal/src/config/bindings.rs1,566Keybinding table, default chords, and the rebindable action registry
zterminal_core/src/query.rs1,785Retroactive relational query: cross-command JOIN over captured OSC 133 output
zterminal_core/src/term/search.rs1,251In-scrollback regex search engine
zterminal/src/renderer/text/builtin_font.rs1,295Embedded fallback glyph font — keeps the renderer self-contained with no external font dependency
crates/zterminal-ledger/src/lib.rs932Command-block ledger: durable capture that survives scrollback eviction, backing retroactive diff / trend / sort
zterminal/src/pane.rs910Native split tree: pane geometry, split / focus / resize / zoom
zterminal_core/src/vi_mode.rs893vi-mode cursor motions, selections, and operators
zterminal/src/config/ui_config.rs791UI config schema: colors, window geometry, opacity, background image
zterminal_core/src/grid/storage.rs769Scrollback ring-buffer storage
zterminal/src/input/keyboard.rs882Keyboard layout / keysym → escape-sequence encoding
zterminal_core/src/shell.rs715OSC 133 shell integration: command-block boundaries, prompt marks, and printed-output capture
zterminal/src/display/hint.rs703Hint overlay: URL and path hints over the grid
zterminal_core/src/selection.rs687Selection model (block / semantic / line) and clipboard text extraction
zterminal_core/src/grid/mod.rs678Grid: cell storage, rows, resize / reflow
TOP 20 SUBTOTAL32,54554.3% of the 59,947-line Rust slice

@DATA-FLOW PIPELINE

Bytes flow from the child PTY through the VT engine into the grid, then onto the GPU. An image scanner sits ahead of the escape parser so Kitty / Sixel / iTerm2 sequences are peeled off and uploaded as textures while ordinary text and control sequences pass through untouched. tmux traffic takes a parallel path over the wire-protocol client.

  child process (shell, vim, htop, …)
       │  PTY
       ▼
  ┌──────────────┐     ┌──────────────────┐     ┌──────────────┐
  │  core/tty/   │────▶│ graphics/scanner │────▶│  core/term/  │
  │  (1,601)     │     │  (peel Kitty /   │     │  (5,392)     │
  │  PTY read/   │     │   Sixel / iTerm2 │     │  VT / xterm  │
  │  write loop  │     │   image seqs)    │     │  parser      │
  └──────────────┘     └────────┬─────────┘     └──────┬───────┘
                                │                       │
                       image bytes                cell writes
                                │                       │
                                ▼                       ▼
                       ┌──────────────┐         ┌──────────────┐
                       │ core/graphics│         │  core/grid/  │
                       │  (2,189)     │         │  (2,519)     │
                       │  placements  │         │  cells +     │
                       │  + GPU queue │         │  scrollback  │
                       └──────┬───────┘         └──────┬───────┘
                              │                        │
                              └───────────┬────────────┘
                                          ▼
                              ┌───────────────────────┐
                              │   renderer/ (4,672)   │
                              │  GLES2 glyph atlas +  │
                              │  image texture blits  │
                              └───────────┬───────────┘
                                          ▼
                              ┌───────────────────────┐
                              │   display/ (4,958)    │
                              │  per-window draw,     │
                              │  panes, overlays      │
                              └───────────────────────┘

  tmux:  crates/ztmux-core (2,359, own repo)  ──imsg / socket──▶  server  (no subprocess)
  input: input/ (2,348)  ──key/mouse → action──▶  event.rs (4,572)  ──▶  term / display

&SUBSYSTEM HIGHLIGHTS

What each major subsystem ships. Nine of these — live tmux config, profile-switchable tmux state, the in-app telemetry dashboard, retroactive output diff, cross-run numeric trend, in-place column sort, live broadcast-divergence, the durable command-block ledger and the cross-command relational JOIN — are terminal-emulator firsts; see Inventions.

GPU renderer

OpenGL ES 2.0 glyph-atlas renderer. Text is shaped into a texture atlas and blitted per cell; inline images upload as GPU textures and blit over the cells they occupy. Ships an embedded fallback font (builtin_font.rs) so the binary is self-contained.

VT engine

Full xterm-compatible VT parsing in core/term/ — vim, tmux, htop, and ncurses apps run correctly. 24-bit truecolor, scrollback, in-scrollback regex search, and a complete vi mode with motions, selections, and operators.

Native tiling splits

An i3-style binary split tree in pane.rs — one independent shell + PTY per pane, GL-scissored into the window, no tmux required. Splits nest arbitrarily; each pane renders in its own sub-viewport. Layouts save / restore the split tree, cwd, and command.

Inline graphics

All three terminal image protocols — Kitty (transmit / display / animation / Unicode placeholders), Sixel, and iTerm2. A scanner peels image sequences ahead of the escape parser; ESC Ptmux;…-wrapped sequences are unwrapped and decoded, so images survive tmux redraws.

First-class tmux

ztmux-core speaks tmux’s client/server wire protocol directly to the Unix socket (imsg framing, protocol v8) — no subprocess. Drives the live tmux tab, Sessions save/restore, cross-pane search, broadcast, and live editing of server options / buffers / keybindings.

In-process control panel

~6.5k lines of JavaScript (consuming the shared zgui-core component library) render 19 tabs — Settings, Dashboard, Commands, Sessions, Layouts, Profiles, Keybindings, Triggers, Hints, Snippets, Processes, Recent dirs, Env vars, Logs, About, and the four tmux surfaces (config, sessions, buffers, keys) in an embedded WebView, plus the command palette, Exposé, sessions, and broadcast overlays. All state lives under ~/.zterminal.


~MEASUREMENT NOTES

How the numbers were counted, so they can be reproduced.


Links