Backend Rendering Patterns
MonoTerm’s Atomic Architecture represents a unique position in the server-side rendering landscape. This page surveys how other systems handle backend rendering and compares them to MonoTerm’s approach.The Rendering Spectrum
Copy
╔═════════════════════════════════════════════════════════════════════╗
║ SERVER-SIDE vs CLIENT-SIDE RENDERING ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ FULLY SERVER-SIDE FULLY CLIENT-SIDE ║
║ ◀─────────────────────────────────────────────────────────────────▶║
║ ║
║ Cloud Gaming RDP VNC MonoTerm Web Term Native Term║
║ │ │ │ │ │ │ ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐║
║ │ Render │ │ Render │ │ Screen │ │ VTE │ │ Raw │ │ VTE │║
║ │ Frame │ │ Command│ │ Capture│ │ Parse │ │ Bytes │ │ Parse │║
║ │ Encode │ │ Send │ │ Send │ │ +Grid │ │ Only │ │+Render │║
║ │ Stream │ │ │ │ │ │ Send │ │ │ │ │║
║ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘║
║ │ │ │ │ │ │ ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ Video Stream Render Pixels Grid Cells Raw Bytes N/A ║
║ Commands ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ Client Work: ║
║ [Decode Only] ◀────────────────────────────────────────────▶ [Full]║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Cloud Gaming Architecture
Cloud gaming represents the most extreme form of server-side rendering.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ CLOUD GAMING PIPELINE (GeForce Now, Xbox Cloud, etc.) ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ DATA CENTER ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐│ ║
║ │ │ GAME │ │ GPU │ │ FRAME │ │ VIDEO ││ ║
║ │ │ ENGINE │───▶│ RENDER │───▶│ CAPTURE │───▶│ ENCODE ││ ║
║ │ │ │ │ │ │ │ │ H.264/5 ││ ║
║ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘│ ║
║ │ ▲ │ │ ║
║ │ │ ▼ │ ║
║ │ ┌──────────┐ ┌──────────┐ │ ║
║ │ │ INPUT │ │ PACKET │ │ ║
║ │ │ HANDLER │◀──────────────────────────────────│ STREAM │ │ ║
║ │ └──────────┘ └──────────┘ │ ║
║ │ │ │ ║
║ └───────────────────────────────────────────────────────┼──────┘ ║
║ │ ║
║ ───────────┼──────── ║
║ Network ║
║ ───────────┼──────── ║
║ │ ║
║ THIN CLIENT ▼ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ ║
║ │ │ VIDEO │ │ FRAME │ │ DISPLAY │ │ ║
║ │ │ DECODE │───▶│ DISPLAY │───▶│ │ │ ║
║ │ │ │ │ │ │ │ │ ║
║ │ └──────────┘ └──────────┘ └──────────┘ │ ║
║ │ │ ║
║ │ Client does: Decode + Display (NO game logic, NO rendering) │ ║
║ │ │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Comparison to MonoTerm
| Aspect | Cloud Gaming | MonoTerm |
|---|---|---|
| Server Output | Encoded video frames | Pre-parsed cell data |
| Encoding Overhead | High (H.264/H.265) | None (JSON/binary) |
| Client Processing | Video decode only | Direct injection only |
| Bandwidth | High (video stream) | Low (cell changes) |
| Latency Source | Encode + network | IPC only |
Remote Desktop Protocols
RDP and VNC represent two different approaches to remote display.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ REMOTE DESKTOP PROTOCOLS COMPARISON ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ RDP (Remote Desktop Protocol) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ SERVER CLIENT │ ║
║ │ ┌────────────────┐ ┌────────────────┐ │ ║
║ │ │ Application │ │ Local │ │ ║
║ │ │ State │ ─── Commands ─▶│ Renderer │ │ ║
║ │ │ │ (Draw text, │ │ │ ║
║ │ │ │ move window)│ │ │ ║
║ │ └────────────────┘ └────────────────┘ │ ║
║ │ │ ║
║ │ Server sends COMMANDS, client RENDERS locally │ ║
║ │ │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ VNC (Virtual Network Computing) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ SERVER CLIENT │ ║
║ │ ┌────────────────┐ ┌────────────────┐ │ ║
║ │ │ Screen │ │ Framebuffer │ │ ║
║ │ │ Capture │ ─── Pixels ───▶│ Display │ │ ║
║ │ │ │ (raw image │ │ │ ║
║ │ │ │ rectangles) │ │ │ ║
║ │ └────────────────┘ └────────────────┘ │ ║
║ │ │ ║
║ │ Server captures ACTUAL screen ──▶ Compresses ──▶ Streams │ ║
║ │ │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
MonoTerm is Most Similar to RDP
| Protocol | Data Type | Server Role | Client Role |
|---|---|---|---|
| RDP | Draw commands | Application host | Local renderer |
| VNC | Pixel rectangles | Screen capture | Display pixels |
| MonoTerm | Terminal cells | VTE parse + state | Display + inject |
Terminal Multiplexers (tmux/screen)
tmux uses a client-server architecture with double VTE parsing.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ TMUX: Double VTE Parsing ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ Shell (bash) ║
║ │ outputs: "\033[31mError\033[0m" ║
║ ▼ ║
║ TMUX Server ║
║ │ VTE Parse #1: Interprets escape sequences ║
║ │ Renders to internal state ║
║ │ Re-encodes as: "\033[31mError\033[0m" ║
║ ▼ ║
║ User's Terminal (iTerm2, etc) ║
║ │ VTE Parse #2: Parses the same sequences AGAIN ║
║ ▼ ║
║ Display ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ MONOTERM: Single VTE Parsing ║
║ ║
║ Shell (bash) ║
║ │ outputs: "\033[31mError\033[0m" ║
║ ▼ ║
║ Rust Alacritty VTE Parser ║
║ │ VTE Parse (only once): Extracts cells + colors ║
║ │ Sends: {cells: [...], fg: "red"} ║
║ ▼ ║
║ xterm.js ║
║ │ Direct injection (NO parsing) ║
║ ▼ ║
║ WebGL Render ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Web Terminal Systems (GoTTY, WeTTY)
Traditional web terminals do all processing in the browser.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ WEB TERMINAL ARCHITECTURE (GoTTY, WeTTY) ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ SERVER ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ ┌──────────┐ ┌────────────────┐ ┌──────────────┐│ ║
║ │ │ PTY │ ────▶ │ Raw Bytes │ ────▶ │ WebSocket ││ ║
║ │ │ (shell) │ │ Forward │ │ Server ││ ║
║ │ └──────────┘ └────────────────┘ └──────────────┘│ ║
║ │ │ │ ║
║ │ Server does: Spawn PTY + Forward bytes │ │ ║
║ │ Server does NOT: Parse VTE sequences │ │ ║
║ │ │ │ ║
║ └───────────────────────────────────────────────────┼──────────┘ ║
║ │ ║
║ WebSocket │ (raw bytes) ║
║ │ ║
║ BROWSER ▼ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ ┌────────────────┐ ┌────────────────┐ ┌────────┐│ ║
║ │ │ WebSocket │ ────▶ │ xterm.js │ ────▶ │ WebGL ││ ║
║ │ │ Client │ │ VTE Parser │ │ Render││ ║
║ │ └────────────────┘ └────────────────┘ └────────┘│ ║
║ │ │ ║
║ │ Browser does: Receive bytes + VTE Parse + Render │ ║
║ │ ALL terminal emulation happens in JavaScript │ ║
║ │ │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
MonoTerm vs Traditional Web Terminals
Copy
╔═══════════════════════════════╦══════════════════════════════════════╗
║ TRADITIONAL (GoTTY) ║ MONOTERM ATOMIC ARCHITECTURE ║
╠═══════════════════════════════╬══════════════════════════════════════╣
║ ║ ║
║ Server: ║ Server: ║
║ • PTY spawn ║ • PTY spawn ║
║ • Byte forwarding ║ • Rust VTE parsing ║
║ ║ • Grid state management ║
║ ║ • ACK Gate flow control ║
║ ║ ║
║ ───────────────────────── ║ ───────────────────────── ║
║ ║ ║
║ Network: ║ Network: ║
║ • Raw bytes ║ • Pre-parsed cells ║
║ • All escape sequences ║ • Color/attribute data ║
║ ║ ║
║ ───────────────────────── ║ ───────────────────────── ║
║ ║ ║
║ Client: ║ Client: ║
║ • JavaScript VTE parse ║ • Direct injection only ║
║ • Storage management ║ • WebGL render ║
║ • WebGL render ║ ║
║ ║ ║
║ CPU Usage: HIGH (JS parsing) ║ CPU Usage: LOW (no parsing) ║
║ ║ ║
╚═══════════════════════════════╩══════════════════════════════════════╝
GPU-Accelerated Native Terminals
Native terminals like Alacritty and Ghostty do everything in one process.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ GPU-ACCELERATED TERMINAL (Alacritty, Ghostty, WezTerm) ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌──────────┐ ┌────────────────┐ ┌────────────────┐ ┌────┐║
║ │ PTY │────▶│ VTE Parser │────▶│ Grid State │──▶│ GPU│║
║ │ │ │ (native) │ │ │ │ │║
║ └──────────┘ └────────────────┘ └────────────────┘ └────┘║
║ ║
║ ALL in same process, NO IPC overhead ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ PERFORMANCE COMPARISON ║
║ ║
║ Alacritty (Rust + OpenGL): ║
║ • VTE Parse: ~500M chars/sec ║
║ • Render: OpenGL with font atlas ║
║ • Latency: ~2ms ║
║ ║
║ xterm.js (JavaScript + WebGL): ║
║ • VTE Parse: ~50M chars/sec ║
║ • Render: WebGL addon ║
║ • Latency: 10x slower parsing than native ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Why MonoTerm Can’t Use Native Terminals
Copy
╔═════════════════════════════════════════════════════════════════════╗
║ NATIVE TERMINAL vs WEB-BASED TRADEOFFS ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ Native (Alacritty/Ghostty): ║
║ ✓ Maximum performance (240 FPS possible) ║
║ ✓ Direct GPU access ║
║ ✓ Low latency ║
║ ✗ Cannot embed in web UI ║
║ ✗ Cannot run AI overlays in same context ║
║ ✗ Cannot share DOM with web components ║
║ ║
║ ───────────────────────────────────────────────────────────────── ║
║ ║
║ Web-based (xterm.js): ║
║ ✓ Embeddable in Tauri ║
║ ✓ AI UI overlays in same DOM ║
║ ✓ Shared state with web components ║
║ ✗ Slow JavaScript VTE parsing ║
║ ║
║ ───────────────────────────────────────────────────────────────── ║
║ ║
║ MONOTERM SOLUTION: ║
║ ✓ Rust VTE parsing (native speed) ║
║ ✓ xterm.js display (web integration) ║
║ ✓ Best of both worlds ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
MonoTerm as Split Rendering
MonoTerm applies the “split rendering” concept from cloud gaming to terminal emulation.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ MONOTERM ATOMIC ARCHITECTURE = SPLIT TERMINAL RENDERING ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ TRADITIONAL SPLIT (Games): ║
║ ║
║ Server Client ║
║ ┌────────────────┐ ┌────────────────┐ ║
║ │ Game Logic │ │ Graphics │ ║
║ │ + Partial │ ─ State ─▶│ Render │ ║
║ │ Render │ │ │ ║
║ └────────────────┘ └────────────────┘ ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ MONOTERM SPLIT: ║
║ ║
║ Server (Rust) Client (xterm.js) ║
║ ┌────────────────┐ ┌────────────────┐ ║
║ │ PTY I/O │ │ Storage │ ║
║ │ + VTE Parse │ ─ Cells ─▶│ Inject + │ ║
║ │ + Grid State │ │ WebGL Render │ ║
║ └────────────────┘ └────────────────┘ ║
║ ║
║ Server does: Semantic processing (what cells contain) ║
║ Client does: Visual rendering (how cells look) ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Summary: Where MonoTerm Fits
Copy
╔═════════════════════════════════════════════════════════════════════╗
║ BACKEND RENDERING PATTERNS TAXONOMY ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ PIXEL-BASED STREAMING │ ║
║ │ │ ║
║ │ Cloud Gaming ─── Video frames ───▶ Decode + Display │ ║
║ │ VNC ─────────── Screen rectangles ───▶ Display │ ║
║ │ │ ║
║ │ Pro: Universal (anything visual) │ ║
║ │ Con: Bandwidth hungry, encoding overhead │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ COMMAND-BASED STREAMING │ ║
║ │ │ ║
║ │ RDP ─────────── Draw commands ───▶ Local render │ ║
║ │ │ ║
║ │ Pro: Efficient, semantic │ ║
║ │ Con: Tied to specific graphics system │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ RAW BYTE STREAMING │ ║
║ │ │ ║
║ │ GoTTY/WeTTY ─── PTY bytes ───▶ Full terminal emulation │ ║
║ │ tmux client ─── VT100 output ───▶ Terminal display │ ║
║ │ │ ║
║ │ Pro: Simple server │ ║
║ │ Con: Heavy client processing │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ SEMANTIC GRID STREAMING ◀─── MONOTERM │ ║
║ │ │ ║
║ │ MonoTerm ───── Parsed cells ───▶ Direct inject + render │ ║
║ │ │ ║
║ │ Pro: Fast parsing (server), light client, keeps terminal │ ║
║ │ features │ ║
║ │ Con: Requires custom protocol │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ MONOTERM INNOVATION: ║
║ ║
║ Taking the "split rendering" concept from cloud gaming/VR and ║
║ applying it to terminal emulation: ║
║ ║
║ • Server handles: PTY I/O + VTE parsing (compute-intensive) ║
║ • Client handles: Display + WebGL render (GPU-bound) ║
║ • Protocol carries: Semantic cell data (not pixels, not raw bytes) ║
║ ║
║ Result: Native parsing speed + Web UI integration ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝