Skip to main content

Architecture Success Factors

The architectural decisions that enabled MonoTerm to solve the AI CLI flickering problem.

The AI-Era Problem

┌───────────────────────────────────────────────────────────────────────┐
│  THE FLICKERING PROBLEM                                                │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    Human Typing:             AI Streaming:                             │
│    ══════════════            ══════════════                            │
│                                                                        │
│    ~5 characters/second      ~50 updates/second                        │
│                                                                        │
│    ┌──────────────────┐      ┌──────────────────┐                      │
│    │  H e l l o       │      │  ****************│  <── Flickering      │
│    │  _               │      │  ****************│  <── Reflow          │
│    │                  │      │  ****************│  <── Eye strain      │
│    └──────────────────┘      └──────────────────┘                      │
│                                                                        │
│    Native terminals optimized for the left.                            │
│    AI CLI tools produce the right.                                     │
│                                                                        │
│    MonoTerm recognized this gap and bridged it.                        │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

The Architecture

┌───────────────────────────────────────────────────────────────────────┐
│  MONOTERM ARCHITECTURE                                                 │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │  portable-pty (WezTerm)                                       │  │
│    │  ════════════════════════════                                 │  │
│    │  - Cross-platform PTY abstraction                             │  │
│    │  - Production-proven in WezTerm                               │  │
│    │  - Role: PTY communication only                               │  │
│    ├─────────────────────────────┬─────────────────────────────────┤  │
│                                  │                                    │
│                                  v                                    │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │  Alacritty VTE Parser                                         │  │
│    │  ════════════════════════════                                 │  │
│    │  - Complete VT100/ANSI parsing                                │  │
│    │  - Production-proven in Alacritty                             │  │
│    │  - Role: Parsing only (Grid storage)                          │  │
│    ├─────────────────────────────┬─────────────────────────────────┤  │
│                                  │                                    │
│                                  v                                    │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │  AtomicState Layer                                            │  │
│    │  ════════════════════════════                                 │  │
│    │  - BSU/ESU detection (Mode 2026)                              │  │
│    │  - Pseudo-BSU/ESU (cursor pattern heuristic)                  │  │
│    │  - Frame synchronization                                      │  │
│    │  - Role: Frame boundary detection                             │  │
│    ├─────────────────────────────┬─────────────────────────────────┤  │
│                                  │                                    │
│                                  v  IPC (Tauri emit)                  │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │  xterm.js (Buffer Direct Injection)                           │  │
│    │  ══════════════════════════════════════                       │  │
│    │  - Parser BYPASSED                                            │  │
│    │  - Pure rendering machine                                     │  │
│    │  - WebGL GPU acceleration                                     │  │
│    │  - Role: Rendering only                                       │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
│                          Tauri (Rust <-> WebView Bridge)               │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 1: Production-Proven Rust Crates

┌───────────────────────────────────────────────────────────────────────┐
│  STANDING ON GIANTS: RUST ECOSYSTEM                                    │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    ┌──────────────────────────┐    ┌──────────────────────────┐        │
│    │                          │    │                          │        │
│    │  portable-pty            │    │  alacritty_terminal      │        │
│    │                          │    │                          │        │
│    │  From: WezTerm           │    │  From: Alacritty         │        │
│    │  Years: 5+ production    │    │  Years: 7+ production    │        │
│    │  Edge cases: Solved      │    │  Edge cases: Solved      │        │
│    │                          │    │                          │        │
│    └──────────────────────────┘    └──────────────────────────┘        │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │  What this means:                                             │  │
│    │                                                               │  │
│    │  - Immediate production-level quality                         │  │
│    │  - Years of PTY edge cases already handled                    │  │
│    │  - Hundreds of VTE parsing edge cases already solved          │  │
│    │  - We focused on the NEW problem (frame synchronization)      │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
│    Recognition: The best code is code we didn't have to write.         │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 2: xterm.js as Pure Renderer

┌───────────────────────────────────────────────────────────────────────┐
│  THE KEY INSIGHT: BYPASS THE PARSER                                    │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    Typical xterm.js usage:                                             │
│    ───────────────────────                                             │
│                                                                        │
│    PTY --> term.write(data) --> Parser (JS) --> Buffer --> Renderer    │
│                                    │                                   │
│                               JavaScript                               │
│                               Single-threaded                          │
│                               GC pauses                                │
│                                                                        │
│    MonoTerm approach:                                                  │
│    ──────────────────                                                  │
│                                                                        │
│    PTY --> Alacritty VTE (Rust) --> Direct Injection --> Renderer      │
│                │                           │                           │
│             Native                    Parser bypassed                  │
│             Multi-threaded            xterm.js renders only            │
│             No GC                                                      │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │  xterm.js role transformation:                                │  │
│    │                                                               │  │
│    │    Before:  Parser + Renderer (heavy)                         │  │
│    │    After:   Renderer only (lightweight)                       │  │
│    │                                                               │  │
│    │  xterm.js becomes a GPU rendering machine.                    │  │
│    │  WebGL draws what Rust prepares.                              │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 3: AtomicState at IPC Boundary

┌───────────────────────────────────────────────────────────────────────┐
│  THE CRITICAL POSITION: WHERE FRAME SYNC HAPPENS                       │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│                                                                        │
│    Rust Backend                          │  WebView Frontend           │
│    ══════════════════════════════════    │  ══════════════════         │
│                                          │                             │
│    PTY --> VTE --> AtomicState ──────────┼─────────> xterm.js          │
│                         │                │                             │
│                         │                │                             │
│              ┌──────────┴───────────┐    │                             │
│              │                      │    │                             │
│              │  - BSU/ESU detect    │    │                             │
│              │  - Pseudo-BSU/ESU    │    │                             │
│              │  - Frame buffer      │    │                             │
│              │  - Diff calculate    │    │                             │
│              │                      │    │                             │
│              └──────────┬───────────┘    │                             │
│                         │                │                             │
│                         v                │                             │
│              GridUpdate (per frame)      │                             │
│                                          │                             │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │  Why this position matters:                                   │  │
│    │                                                               │  │
│    │  - Processing happens BEFORE IPC --> minimal data transfer    │  │
│    │  - Rust handles heavy work --> no GC, multi-threaded          │  │
│    │  - Frame-level emission --> JS just renders complete frames   │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 4: Pseudo-BSU/ESU (Original Contribution)

┌───────────────────────────────────────────────────────────────────────┐
│  PSEUDO-BSU/ESU: WHAT MONOTERM ADDS                                    │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    Research Finding (modern terminals analyzed):                       │
│    ═════════════════════════════════════════════                       │
│                                                                        │
│    - Alacritty:  Cursor affects rendering (not frame boundary)         │
│    - Ghostty:    Cursor affects frame content (not frame boundary)     │
│    - WezTerm:    Cursor visibility check only                          │
│    - xterm.js:   Cursor draw decision only                             │
│    - Hyper:      Delegates to xterm.js                                 │
│                                                                        │
│    None use cursor pattern AS frame boundary.                          │
│                                                                        │
│    ───────────────────────────────────────────────────────────────     │
│                                                                        │
│    MonoTerm Pseudo-BSU/ESU:                                            │
│    ═══════════════════════                                             │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │  AI CLI Pattern (most TUI apps):                              │  │
│    │                                                               │  │
│    │    Cursor hide  <──  "Frame start" (begin buffering)          │  │
│    │    ... output ...                                             │  │
│    │    Cursor show  <──  "Frame end" (flush and render)           │  │
│    │                                                               │  │
│    │  This is a HEURISTIC, not a standard.                         │  │
│    │  But it works because AI CLI tools follow this pattern.       │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
│    This is MonoTerm's original contribution:                           │
│    Recognizing that cursor pattern CAN serve as frame boundary.        │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 5: Tauri as the Bridge

┌───────────────────────────────────────────────────────────────────────┐
│  TAURI: ENABLING THE HYBRID ARCHITECTURE                               │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    The architecture requires:                                          │
│    ══════════════════════════                                          │
│                                                                        │
│    - Rust crates (portable-pty, alacritty_terminal)                    │
│    - Web rendering (xterm.js in WebView)                               │
│    - Efficient IPC between them                                        │
│                                                                        │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │                     Tauri Provides                            │  │
│    │                                                               │  │
│    │    ┌──────────────────┐             ┌──────────────────┐      │  │
│    │    │                  │             │                  │      │  │
│    │    │  Rust Backend    │ <── IPC ──> │  WebView         │      │  │
│    │    │                  │             │                  │      │  │
│    │    │  - PTY client    │             │  - xterm.js      │      │  │
│    │    │  - VTE parser    │             │  - HTML/CSS      │      │  │
│    │    │  - AtomicState   │             │  - Extensions    │      │  │
│    │    │  - SessionActor  │             │                  │      │  │
│    │    │                  │             │                  │      │  │
│    │    └──────────────────┘             └──────────────────┘      │  │
│    │                                                               │  │
│    │    + Sidecar support (PTY Daemon survives app crashes)        │  │
│    │    + Type-safe IPC (Rust <-> TypeScript)                      │  │
│    │    + Lightweight binary (~50MB vs ~200MB)                     │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
│    Tauri made "Rust parsing + Web rendering" possible.                 │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Success Factor 6: Web-Based Extensibility

┌───────────────────────────────────────────────────────────────────────┐
│  THE EXTENSIBILITY ADVANTAGE                                           │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    Native terminal UI:           MonoTerm UI:                          │
│    ═══════════════════           ════════════                          │
│                                                                        │
│    Prompt Box?                   Prompt Box?                           │
│    --> OpenGL rendering          --> HTML div + CSS                    │
│                                                                        │
│    Markdown preview?             Markdown preview?                     │
│    --> Custom pipeline           --> marked.js, one line               │
│                                                                        │
│    Image display?                Image display?                        │
│    --> Terminal graphics         --> <img> tag                         │
│                                                                        │
│    AI API integration?           AI API integration?                   │
│    --> Rust HTTP client          --> fetch(), one line                 │
│                                                                        │
│    Theme customization?          Theme customization?                  │
│    --> Recompile or config       --> CSS file swap                     │
│                                                                        │
│    ┌───────────────────────────────────────────────────────────────┐  │
│    │                                                               │  │
│    │  The insight:                                                 │  │
│    │                                                               │  │
│    │  Terminal = Rust (performance-critical parsing)               │  │
│    │  UI/UX = Web (rapid iteration, rich features)                 │  │
│    │                                                               │  │
│    │  Each layer does what it does best.                           │  │
│    │                                                               │  │
│    └───────────────────────────────────────────────────────────────┘  │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

The Complete Picture

┌───────────────────────────────────────────────────────────────────────┐
│  MONOTERM SUCCESS FORMULA                                              │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    1. Production-Proven Rust Crates                                    │
│       ─────────────────────────────────                                │
│       portable-pty + alacritty_terminal                                │
│       --> Immediate production quality                                 │
│                                                                        │
│    2. xterm.js Parser Bypass                                           │
│       ──────────────────────────                                       │
│       Direct buffer injection                                          │
│       --> xterm.js becomes pure GPU renderer                           │
│                                                                        │
│    3. AtomicState at IPC Boundary                                      │
│       ───────────────────────────────                                  │
│       Frame synchronization in Rust, before data transfer              │
│       --> Flickering solved at the right layer                         │
│                                                                        │
│    4. Pseudo-BSU/ESU (Original Contribution)                           │
│       ──────────────────────────────────────                           │
│       Cursor pattern as frame boundary heuristic                       │
│       --> Works for AI CLI tools without Mode 2026                     │
│                                                                        │
│    5. Tauri as Bridge                                                  │
│       ─────────────────                                                │
│       Rust backend + WebView frontend                                  │
│       --> Made the hybrid architecture possible                        │
│                                                                        │
│    6. Web-Based Extensibility                                          │
│       ─────────────────────────                                        │
│       HTML/CSS/JS for UI, Rust for performance                         │
│       --> Each layer does what it does best                            │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘

Conclusion

MonoTerm’s success came from recognizing the right boundaries:
  • PTY communication: Let WezTerm’s portable-pty handle it
  • VTE parsing: Let Alacritty’s parser handle it
  • Frame synchronization: Handle at IPC boundary (AtomicState)
  • Rendering: Let xterm.js WebGL handle it
  • Glue: Let Tauri bridge Rust and Web
The original contribution is Pseudo-BSU/ESU: recognizing that cursor patterns can serve as frame boundaries for AI CLI tools.
┌───────────────────────────────────────────────────────────────────────┐
│  THE RIGHT COMPONENTS AT THE RIGHT BOUNDARIES                          │
├───────────────────────────────────────────────────────────────────────┤
│                                                                        │
│    portable-pty     -->  PTY communication                             │
│    Alacritty VTE    -->  Parsing                                       │
│    AtomicState      -->  Frame synchronization (NEW)                   │
│    xterm.js         -->  Pure rendering                                │
│    Tauri            -->  Rust <-> Web bridge                           │
│                                                                        │
│    + Pseudo-BSU/ESU: The original heuristic (NEW)                      │
│                                                                        │
│    What we add: The frame boundary recognition                         │
│    that solves AI CLI flickering.                                      │
│                                                                        │
└───────────────────────────────────────────────────────────────────────┘