xterm.js as Renderer
In MonoTermβs Atomic Architecture, xterm.js is demoted from a full terminal emulator to a specialized display component.What is xterm.js?
xterm.js is a complete terminal emulator written in TypeScript.Copy
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β xterm.js - COMPLETE TERMINAL EMULATOR β
β β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β xterm.js β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β VTE Parser Layer β β β
β β β β β β
β β β * EscapeSequenceParser β β β
β β β * InputHandler β β β
β β β * OSC/CSI/DCS handlers β β β
β β β * UTF-8 decoder β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Storage Layer β β β
β β β β β β
β β β * Primary/Alternate buffers β β β
β β β * Line storage β β β
β β β * Circular scrollback β β β
β β β * Cursor state β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Renderer Layer β β β
β β β β β β
β β β * WebGL Renderer (fast) β β β
β β β * Canvas Renderer (fallback) β β β
β β β * DOM Renderer (accessible) β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Interaction Layer β β β
β β β β β β
β β β * Selection β β β
β β β * Mouse handling β β β
β β β * Keyboard handling β β β
β β β * Clipboard β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β xterm.js can work standalone - no backend needed. β
β term.write("\x1b[32mHello\x1b[0m") displays green text. β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The Demotion
In Atomic Architecture, we use only parts of xterm.js.Copy
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β xterm.js IN ATOMIC ARCHITECTURE β
β β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β xterm.js β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β VTE Parser Layer β β β
β β β β β β
β β β βββββββββββββββββββββββ β β β
β β β β β β β β
β β β β BYPASSED β β β β
β β β β β β β β
β β β β Not used at β β β β
β β β β all in Atomic β β β β
β β β β Architecture β β β β
β β β β β β β β
β β β βββββββββββββββββββββββ β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββββ β β
β β β Direct injection β β β
β β β from Rust backend β β β
β β β β β β
β β β Pre-parsed cells β β β
β β β injected directly β β β
β β ββββββββββββ¬ββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Storage Layer β β β
β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β β β
β β β β USED AS STORAGE β β β β
β β β β β β β β
β β β β Receives pre-parsed cells β β β β
β β β β from Grid Injector β β β β
β β β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Renderer Layer β β β
β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β β β
β β β β USED FOR DISPLAY β β β β
β β β β β β β β
β β β β WebGL renders stored cells β β β β
β β β β GPU-accelerated display β β β β
β β β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β v β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Interaction Layer β β β
β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β β β
β β β β USED AS-IS β β β β
β β β β β β β β
β β β β Selection, scrollbar, β β β β
β β β β clipboard all work normally β β β β
β β β β β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Feature-by-Feature Breakdown
What we use and what we bypass.Copy
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β xterm.js FEATURE USAGE IN ATOMIC ARCHITECTURE β
β β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β BYPASSED (VTE Parsing) - Replaced by Alacritty β β
β β β β
β β These components are NEVER called in Atomic Architecture: β β
β β β β
β β * EscapeSequenceParser β β
β β State machine for escape sequences β β
β β β β
β β * InputHandler β β
β β 50+ CSI handlers (cursorUp, eraseInDisplay, etc) β β
β β β β
β β * OscParser, DcsParser β β
β β Operating system commands, device control strings β β
β β β β
β β * term.write() β β
β β We NEVER call this method in Atomic Mode β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β USED (Storage) β β
β β β β
β β These components store the data we inject: β β
β β β β
β β * Primary and alternate screen buffers β β
β β β β
β β * Line storage with internal data arrays β β
β β β β
β β * Cursor position (we set these directly) β β
β β β β
β β * Scrollback offset β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β USED (Rendering) β β
β β β β
β β These components display the stored cells: β β
β β β β
β β * WebGL Renderer β β
β β GPU-accelerated rendering (via addon) β β
β β β β
β β * Canvas Renderer β β
β β Fallback for non-WebGL browsers β β
β β β β
β β * term.refresh() β β
β β Triggers re-render after direct injection β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β USED (Interaction) β β
β β β β
β β User interaction features work unchanged: β β
β β β β
β β * SelectionService β β
β β Text selection with mouse/keyboard β β
β β β β
β β * Viewport (scrollbar) β β
β β Scrolling through history β β
β β β β
β β * Clipboard integration β β
β β Copy/paste functionality β β
β β β β
β β * FitAddon (auto-resize) β β
β β β β
β β * WebLinksAddon (clickable URLs) β β
β β β β
β β * SearchAddon (find in scrollback) β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The Data Path Comparison
Visual comparison of how data flows.Copy
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β TRADITIONAL xterm.js DATA PATH β
β β
β β
β Raw PTY bytes: "\x1b[32mHello\x1b[0m World" β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β term.write(bytes) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β EscapeSequenceParser β β
β β β β
β β State machine processes byte by byte: β β
β β \x1b βββΆ ESCAPE state β β
β β [ βββΆ CSI state β β
β β 3 βββΆ param = 3 β β
β β 2 βββΆ param = 32 β β
β β m βββΆ SGR action (set color 32 = green) β β
β β H βββΆ GROUND state, print 'H' β β
β β ... β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Storage Layer β β
β β Cells populated one at a time β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β WebGL Renderer β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β SLOW: JavaScript processes every byte individually β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β ATOMIC ARCHITECTURE DATA PATH β
β β
β β
β Raw PTY bytes: "\x1b[32mHello\x1b[0m World" β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Rust Alacritty VTE Parser β β
β β β β
β β Parses everything at native speed β β
β β Updates internal grid state β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β GridUpdate { rows: [...], cursor: {...} } β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Grid Injector β β
β β β β
β β Receives pre-parsed cell data β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β (BYPASSES term.write, EscapeSequenceParser, β
β β InputHandler - all skipped entirely) β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Storage Layer (Direct Write) β β
β β β β
β β Cells written directly to internal arrays β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β v β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β WebGL Renderer β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β FAST: Rust does the heavy lifting β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Why Not Replace xterm.js Entirely?
If we bypass the parser, why keep xterm.js at all?Copy
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β WHY WE STILL NEED xterm.js β
β β
β β
β We could theoretically replace xterm.js with a custom β
β renderer, but xterm.js provides many features for free: β
β β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β FEATURES WE GET FOR FREE β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β WebGL Renderer β β β
β β β * GPU-accelerated text rendering β β β
β β β * Glyph atlas management β β β
β β β * Efficient dirty-rectangle updates β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β Text Selection β β β
β β β * Mouse drag selection β β β
β β β * Double-click word select β β β
β β β * Triple-click line select β β β
β β β * Rectangle select (Alt+drag) β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β Scrolling β β β
β β β * Smooth scrolling β β β
β β β * Scrollbar with drag support β β β
β β β * Wheel scroll with momentum β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β Addons β β β
β β β * FitAddon (auto-resize) β β β
β β β * WebLinksAddon (clickable URLs) β β β
β β β * SearchAddon (find in scrollback) β β β
β β β * Unicode11Addon (wide character support) β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β Reimplementing all of this would take months. β
β Better to reuse what works and bypass only the slow parts. β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The βDumb Rendererβ Concept
A summary of xterm.jsβs new role.Copy
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β xterm.js: FROM "TERMINAL EMULATOR" TO "TERMINAL RENDERER" β
β β
β β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β BEFORE (Traditional Usage) β β
β β β β
β β β β
β β xterm.js β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β "I am a complete terminal emulator. β β β
β β β Give me raw bytes, I will parse them, β β β
β β β update my storage, and render them." β β β
β β β β β β
β β β Input: Raw PTY bytes β β β
β β β Output: Rendered terminal β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β AFTER (Atomic Architecture) β β
β β β β
β β β β
β β xterm.js β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β β
β β β "I am now a display component. β β β
β β β Give me cell data, I will store it β β β
β β β and render it. No parsing needed." β β β
β β β β β β
β β β Input: Pre-parsed cell grid β β β
β β β Output: Rendered terminal β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β β
β The "intelligence" (VTE parsing) moved to Rust. β
β xterm.js is now a "dumb" but capable display. β
β β
β This is NOT a criticism of xterm.js. β
β It's an optimization for our specific use case. β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Summary
| Feature | Traditional xterm.js | MonoTerm Atomic Architecture |
|---|---|---|
| VTE Parsing | JavaScript | Rust (Alacritty) - 10x faster |
| term.write() | Used | Bypassed |
| Storage | Used | Used (direct injection) |
| WebGL Rendering | Used | Used |
| Selection | Used | Used |
| Scrolling | Used | Used |
| Addons | Used | Used |