>_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.
Crate Distribution — 59,947 Rust lines
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.
| Subsystem | Key paths | Lines | % | Share | Description |
|---|---|---|---|---|---|
| Config & settings | config/, settings.rs, migrate/ | 8,197 | 13.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 core | event.rs, window_context.rs, pane.rs, main.rs, daemon.rs | 9,321 | 15.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 engine | core/term/ | 5,579 | 9.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 & windowing | display/ | 5,671 | 9.5% | Per-window draw orchestration, damage tracking, cursor and overlays, hint / hyperlink overlay, OS window creation and management. | |
| GPU renderer | renderer/ | 5,217 | 8.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 waits | expect.rs, quorum.rs, snapshot.rs, query_pane.rs, zbus.rs, filebrowser.rs | 4,684 | 7.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 intelligence | core/query.rs, core/shell.rs, core/column.rs, core/diff.rs, core/metric.rs, ledger.rs, crates/zterminal-ledger/ | 4,859 | 8.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 & scrollback | core/grid/ | 2,822 | 4.7% | Cell storage, rows, resize / reflow, and the scrollback ring-buffer storage. | |
| Utilities | cli.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.rs | 2,837 | 4.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 & keybindings | input/ | 2,512 | 4.2% | Key / mouse → action mapping, modifier handling, keysym → escape-sequence encoding, bracketed paste. | |
| Inline graphics | core/graphics/ | 2,189 | 3.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 / TTY | core/tty/ | 1,601 | 2.7% | Pseudo-terminal spawn and I/O: child process, resize, and the read/write loop feeding the VT engine. | |
| Core event loop & index | core/event_loop.rs, index.rs, sync.rs | 1,015 | 1.7% | The terminal engine’s event loop, grid coordinate / index types, shell helpers, and synchronization primitives shared with the shell. | |
| vi mode | core/vi_mode.rs | 893 | 1.5% | vi-style cursor motions, selections, and operators over the grid and scrollback. | |
| Selection | core/selection.rs | 687 | 1.1% | Selection model (block / semantic / line) and clipboard text extraction. | |
| Config derive macros | zterminal_config*/ | 604 | 1.0% | Procedural-macro config deserialization (struct / enum) and serde replace support, plus the thin config crate entry. | |
| macOS platform | macos/ | 623 | 1.0% | macOS-specific glue: native menu, global hotkey (Quake dropdown), and app integration. | |
| Polling | polling/ | 399 | 0.7% | Periodic polling for telemetry / tmux refresh feeding the dashboard. | |
| Windows platform | windows/ | 237 | 0.4% | Windows-specific glue: the native menu integration. | |
| TOTAL | 59,947 | 100% | |||
$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.
| File | Lines | Role |
|---|---|---|
| zterminal/src/event.rs | 5,139 | Central event loop: window / keyboard / mouse / IPC event dispatch and the application state machine |
| zterminal_core/src/term/mod.rs | 3,944 | Terminal state: the VT / xterm parser core, grid mutation, modes, cursor, charsets |
| zterminal/src/settings.rs | 3,178 | Settings model and persistence, bridged to the WebView control panel |
| zterminal/src/window_context.rs | 2,790 | Per-window context: tabs, panes, focus, MRU quick-switch |
| zterminal/src/display/mod.rs | 2,007 | Display driver: per-window draw orchestration, damage, cursor, overlays |
| zterminal/src/input/mod.rs | 1,630 | Input handling: key / mouse → action mapping, modifiers, bracketed paste |
| zterminal/src/config/bindings.rs | 1,566 | Keybinding table, default chords, and the rebindable action registry |
| zterminal_core/src/query.rs | 1,785 | Retroactive relational query: cross-command JOIN over captured OSC 133 output |
| zterminal_core/src/term/search.rs | 1,251 | In-scrollback regex search engine |
| zterminal/src/renderer/text/builtin_font.rs | 1,295 | Embedded fallback glyph font — keeps the renderer self-contained with no external font dependency |
| crates/zterminal-ledger/src/lib.rs | 932 | Command-block ledger: durable capture that survives scrollback eviction, backing retroactive diff / trend / sort |
| zterminal/src/pane.rs | 910 | Native split tree: pane geometry, split / focus / resize / zoom |
| zterminal_core/src/vi_mode.rs | 893 | vi-mode cursor motions, selections, and operators |
| zterminal/src/config/ui_config.rs | 791 | UI config schema: colors, window geometry, opacity, background image |
| zterminal_core/src/grid/storage.rs | 769 | Scrollback ring-buffer storage |
| zterminal/src/input/keyboard.rs | 882 | Keyboard layout / keysym → escape-sequence encoding |
| zterminal_core/src/shell.rs | 715 | OSC 133 shell integration: command-block boundaries, prompt marks, and printed-output capture |
| zterminal/src/display/hint.rs | 703 | Hint overlay: URL and path hints over the grid |
| zterminal_core/src/selection.rs | 687 | Selection model (block / semantic / line) and clipboard text extraction |
| zterminal_core/src/grid/mod.rs | 678 | Grid: cell storage, rows, resize / reflow |
| TOP 20 SUBTOTAL | 32,545 | 54.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.
- Rust source lines (59,947) & files (113) —
wc -lover every*.rsunder the five workspace crates’src/trees (zterminal,zterminal_core,zterminal_config,zterminal_config_derive,crates/zterminal-ledger), excludingtarget/and thezgui-coresubmodule. - Code lines (44,844) —
tokei, Rust only, excluding comments and blank lines. - Test functions (600) — count of
#[test]/#[tokio::test]attributes across the same trees. - Control-panel JS (6,481) —
wc -loversettings/+frontend/JavaScript, excluding the vendoredzgui-corecomponent library. - Dependencies — 41 direct dependencies declared in
zterminal/Cargo.toml(29 plain, 3 path deps on the sibling crates, 9 target-gated); 573 total crates resolved inCargo.lock(full transitive tree). - Subsystem percentages — each subsystem’s total source lines as a fraction of 59,947; rows sum to 100%.
Links
- Docs — zterminal documentation
- Inventions — terminal-emulator firsts
- Source — GitHub repo