Roo-Code/docs/opentui-baseline.md
Roo Code e5c2a97af5 docs: add Wave 0 OpenTUI migration deliverables (ADR, parity matrix, baseline, implementation plan)
Addresses Issue #11705 Wave 0 Discovery acceptance criteria:
- ADR: Node.js-first with opt-in Bun experimental strategy
- Feature parity matrix: 54 items cataloged across Ink components, hooks, and tools
- Performance baseline: startup, latency, render cadence, memory benchmarks
- Implementation plan: 8-week roadmap across 60 tasks in 5 waves
- Terminal compatibility matrix for cross-platform validation
2026-02-22 18:20:38 +00:00

7 KiB

CLI Performance Baseline: Ink UI

Issue: #11705 Date: 2026-02-22 Purpose: Establish baseline performance metrics for the current Ink-based CLI UI to enable comparison with OpenTUI prototype.

Methodology

Measurements should be taken on a standardized environment:

  • Hardware: Modern laptop/desktop (Apple M-series or equivalent x86_64)
  • Node.js: v22 LTS
  • Terminal: iTerm2 (macOS), GNOME Terminal (Linux), Windows Terminal (Windows)
  • Measurement tool: process.hrtime.bigint() instrumentation, node --cpu-prof, node --heap-prof

Each metric should be measured across 10 runs with the median reported.

Metrics

1. Startup Time

Time from process start to first UI frame rendered.

Metric Description Target Measurement
Cold start First run after clearing module cache process.hrtime from entry to first Ink render() call
Warm start Subsequent runs with module cache Same as above
TTY detection Time to determine TUI vs non-TUI mode run.ts TTY check to renderer selection
React hydration Time for React/Ink to initialize component tree Ink render() call to first useEffect fire

Expected baseline (Ink):

  • Cold start: ~300-500ms (includes module loading, React init, Ink renderer setup)
  • Warm start: ~150-250ms
  • TTY detection: <1ms (synchronous process.stdin.isTTY check)

2. Input Latency

Time from keypress to visible UI update.

Metric Description Target Measurement
Single character Typing a character in the input field Keypress event to re-render completion
Backspace Deleting a character Same as above
Cursor navigation Arrow key movement Keypress to cursor position update
Autocomplete trigger Typing @ or / to open autocomplete Keypress to picker display
Autocomplete selection Selecting an item from picker Enter key to picker close + text insert

Expected baseline (Ink):

  • Single character input: ~8-16ms (Ink batches renders at ~60fps)
  • Autocomplete trigger: ~16-32ms (state update + picker render)
  • Selection: ~16ms (state update + re-render)

3. Render Cadence

Frame timing for continuous updates (e.g., streaming AI responses).

Metric Description Target Measurement
Idle render rate Renders per second when no updates Should be 0 (Ink only renders on state change)
Streaming render rate Renders per second during message streaming Ink throttled to ~30fps by default
Scroll render rate Renders during scroll through history Depends on ScrollArea implementation
Max render time Longest single render cycle console.time around render function

Expected baseline (Ink):

  • Idle: 0 renders/sec (event-driven)
  • Streaming: ~15-30 renders/sec (Ink's internal throttle)
  • Scroll: ~30 renders/sec
  • Max render time: <16ms for typical content, <50ms for large message histories

4. Memory Usage

Heap consumption across different UI states.

Metric Description Target Measurement
Baseline heap Memory after initial render with empty chat process.memoryUsage().heapUsed
After 10 messages Heap after 10 chat messages rendered Same
After 100 messages Heap after 100 chat messages with scroll Same
Peak heap Maximum heap during heavy rendering --max-old-space-size monitoring
GC pressure Frequency and duration of garbage collection --trace-gc flag

Expected baseline (Ink):

  • Baseline heap: ~30-50MB (React + Ink + Zustand + component tree)
  • After 10 messages: ~40-60MB
  • After 100 messages: ~60-100MB (depends on message content size)
  • Peak heap: ~80-120MB during rapid streaming

5. Bundle Size

Size of the built CLI artifact.

Metric Description Target Measurement
Total bundle Size of dist/index.js ls -la dist/index.js
Ink dependency tree Size of ink + react + @inkjs/ui in node_modules du -sh on relevant directories
UI-specific code Size of apps/cli/src/ui/ source find ... -exec wc -c

Current measurements:

  • UI source: 69 files, 10,619 LOC
  • Key dependencies: ink (6.6.0), react (19.1.0), @inkjs/ui (2.0.0), zustand (5.0.0)

Instrumentation Plan

To collect these metrics, the following instrumentation should be added:

Phase 1: Non-invasive (no code changes)

# Startup time
time node dist/index.js --help

# Memory baseline
node --expose-gc --max-old-space-size=256 dist/index.js --print "hello"

# CPU profile
node --cpu-prof dist/index.js --print "hello"

# Heap snapshot
node --heap-prof dist/index.js --print "hello"

Phase 2: Instrumented (minimal code changes)

Add timing markers at key points in the render pipeline:

  1. run.ts -- Process start timestamp
  2. App.tsx -- First render timestamp (via useEffect)
  3. MultilineTextInput.tsx -- Input event to render completion
  4. ScrollArea.tsx -- Scroll render timing
  5. ChatHistoryItem.tsx -- Message render timing

Phase 3: Automated benchmark suite

Create a benchmark script that:

  1. Launches the CLI in TUI mode with a mock backend
  2. Simulates keypress sequences
  3. Records render timings via process instrumentation
  4. Outputs a JSON report for comparison

Terminal Compatibility Matrix

Terminal OS ANSI Support 256 Color True Color Unicode Mouse Notes
iTerm2 macOS Full Yes Yes Yes Yes Primary dev terminal
Terminal.app macOS Full Yes Limited Yes No Default macOS terminal
GNOME Terminal Linux Full Yes Yes Yes Yes Default Ubuntu/GNOME
Windows Terminal Windows Full Yes Yes Yes Yes Modern Windows default
tmux Cross-platform Full Yes Varies Yes Yes Needs TERM=xterm-256color
VS Code Terminal Cross-platform Full Yes Yes Yes Yes Common dev environment
Alacritty Cross-platform Full Yes Yes Yes Yes GPU-accelerated
Warp macOS Full Yes Yes Yes Yes Modern terminal

Known Issues

  • tmux: True color support requires set -g default-terminal "tmux-256color" in tmux.conf
  • Terminal.app: No true color support; falls back to 256 color palette
  • Older Windows cmd.exe: Not supported (use Windows Terminal instead)
  • SSH sessions: Terminal capabilities depend on client terminal, not server

Comparison Framework

When OpenTUI prototype is ready, compare using this template:

Metric Ink Baseline OpenTUI Prototype Delta Notes
Cold start ___ ms ___ ms ___%
Warm start ___ ms ___ ms ___%
Input latency ___ ms ___ ms ___%
Streaming FPS ___ fps ___ fps ___%
Baseline heap ___ MB ___ MB ___%
Bundle size ___ MB ___ MB ___%