Roo-Code/docs/adr/cli-opentui-runtime.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

4.9 KiB

ADR: CLI OpenTUI Runtime Strategy

  • Status: Proposed
  • Date: 2026-02-22
  • Issue: #11705
  • Decision Makers: CLI team, core maintainers

Context

The Roo CLI (apps/cli) currently uses Ink v6.6.0 with React 19 for terminal UI rendering. The codebase spans ~10,619 LOC across 69 files in apps/cli/src/ui/. OpenTUI has been proposed as an alternative renderer offering potentially better performance and native terminal integration.

Current Stack

Layer Technology Version
Renderer Ink 6.6.0
Component library @inkjs/ui 2.0.0
UI framework React 19.1.0
State management Zustand 5.0.0
Runtime Node.js >=18
Build tsup 8.4.0
Test Vitest + ink-testing-library 4.0.0

Key Constraints

  1. OpenTUI has no public npm package. There is no published opentui package on npm. Integration requires either vendoring the source, using a git dependency, or waiting for an official release.
  2. OpenTUI's primary target is Bun. The library is designed for the Bun runtime, with Node.js support being secondary or incomplete.
  3. The CLI ships as a Node.js application. The @roo-code/cli package targets Node.js and is distributed via npm. Switching the runtime to Bun would affect the entire deployment pipeline and user installation experience.
  4. Ink is deeply integrated. All 69 UI files import from ink or @inkjs/ui. The Ink-specific APIs used include Box, Text, useInput, useApp, Select, Spinner, measureElement, DOMElement, and Newline.
  5. Non-TUI modes must remain unaffected. The --print flag and --output-format stream-json mode bypass the Ink renderer entirely (via TTY detection in run.ts) and must continue to work regardless of renderer choice.

Decision

Node.js-first with opt-in Bun experimental support.

The CLI will continue to target Node.js as the primary runtime. OpenTUI integration, if pursued beyond prototype phase, will be gated behind an experimental --runtime bun flag (or similar mechanism). The Ink-based UI will remain the default and production renderer.

Rationale

  1. User compatibility. The vast majority of CLI users run Node.js. Requiring Bun would be a breaking change that limits adoption.
  2. No npm package available. Without a published npm package, OpenTUI cannot be added as a standard dependency. This makes production use premature.
  3. Incremental migration path. A dual-renderer architecture (Ink default, OpenTUI opt-in) allows evaluation without risk to existing users.
  4. Bun adoption trend. If Bun gains wider adoption and OpenTUI publishes an npm package, the experimental flag can be promoted to default in a future release.

Alternatives Considered

1. Full Bun migration

Replace Node.js runtime entirely with Bun for the CLI package.

  • Pros: Native OpenTUI support, potentially faster startup
  • Cons: Breaking change for all users, requires Bun installation, npm distribution story unclear, affects CI/CD pipeline
  • Verdict: Rejected -- too disruptive for an experimental evaluation

2. Node.js-only with OpenTUI shim

Create a compatibility layer that runs OpenTUI's rendering primitives on Node.js without Bun.

  • Pros: No runtime change needed
  • Cons: Significant engineering effort, unclear if OpenTUI's internals can run on Node.js, maintenance burden
  • Verdict: Deferred -- worth investigating if OpenTUI publishes Node.js support

3. Keep Ink, optimize existing renderer

Focus on optimizing the current Ink-based UI instead of migrating.

  • Pros: No migration cost, proven technology, large community
  • Cons: May not achieve the performance improvements that motivated the evaluation
  • Verdict: Fallback option if OpenTUI evaluation does not yield meaningful improvements

Consequences

Positive

  • No breaking changes to existing users
  • Clear experimental boundary via feature flag
  • Allows data-driven decision based on prototype results
  • Maintains full backward compatibility with --print and --output-format modes

Negative

  • Dual-renderer maintenance overhead during evaluation period
  • OpenTUI prototype may require vendored dependencies
  • Additional CI complexity for Bun-based test paths

Neutral

  • ADR can be revisited once OpenTUI publishes an npm package or Node.js support improves
  • The feat/cli-ui-next-opentui branch contains an existing SolidJS/OpenTUI prototype that can inform further work

Implementation Notes

  • Feature flag: --ui opentui (opt-in, defaults to ink)
  • New UI code goes in apps/cli/src/ui-next/ (already scaffolded on feat/cli-ui-next-opentui branch)
  • Existing apps/cli/src/ui/ remains untouched
  • Entry point in apps/cli/src/commands/cli/run.ts already has TTY detection logic that can be extended for renderer selection