Skip to Content
ADRsADR-003 Terminal backend

ADR-003: Terminal Backend Selection

Status: Accepted

Context

FrankenTUI needs a terminal backend that provides:

  • Raw mode lifecycle management (enter/exit).
  • Event reading (keyboard, mouse, resize, paste, focus).
  • Terminal capability detection.
  • Cross-platform support (Linux, macOS, Windows best-effort).

The backend choice is foundational and extremely hard to change later. It affects:

  • Correctness of terminal cleanup (on normal exit AND panic).
  • Platform reach and feature availability.
  • Maintenance burden and dependency complexity.

Decision

Crossterm is the v1 terminal backend.

Evaluation Matrix

Candidates Considered

BackendUnixWindowsAsyncMaintenanceNotes
CrosstermYesYesOptionalActiveSelected
termwizYesPartialNoActiveMore complex API
termionYesNoNoLowUnix-only, simpler
custom termiosYesNoN/AHighMaximum control + burden

Crossterm Functionality Validated (Spike bd-10i.1.3)

FeatureAPIStatus
Raw modeenable_raw_mode() / disable_raw_mode()Works
Alternate screenEnterAlternateScreen / LeaveAlternateScreenWorks
Cursor show/hideShow / HideWorks
Mouse (SGR)EnableMouseCapture / DisableMouseCaptureWorks
Bracketed pasteEnableBracketedPaste / DisableBracketedPasteWorks
Focus eventsEnableFocusChange / DisableFocusChangeWorks
Resize eventsEvent::Resize(cols, rows)Works
Bounded readspoll(timeout)Works

Cleanup Discipline

Crossterm’s stateless design requires explicit cleanup, which we handle via Drop:

impl Drop for TerminalSession { fn drop(&mut self) { // Disable features in reverse order // Show cursor // Exit raw mode // Flush stdout } }

This guarantees cleanup on:

  • Normal function return.
  • Early return via ? operator.
  • Panic unwinding (default in debug, opt-in in release).

Platform Coverage

PlatformRaw ModeEventsMousePasteFocus
LinuxYesYesYesYesYes
macOSYesYesYesYesYes
WindowsYesYesPartialPartialPartial

Windows limitations are documented in ADR-004.

Alternatives Considered

termwiz

  • More comprehensive API but more complex.
  • Stronger opinions about rendering model.
  • Would constrain our architecture choices.

termion

  • Simpler, lighter weight.
  • Unix-only (no Windows support).
  • Less active maintenance.

Custom termios

  • Maximum control.
  • Massive maintenance burden.
  • Would duplicate existing battle-tested code.

Consequences

Positive

  • Cross-platform support out of the box.
  • Active maintenance and community.
  • Familiar API for Rust TUI ecosystem.
  • Handles edge cases we’d otherwise miss.

Negative

  • External dependency (can’t inline fix bugs).
  • Some Windows features are best-effort.
  • May need to work around crossterm opinions.

Mitigation

  • Abstract crossterm behind our own types (TerminalSession, Event).
  • Document Windows limitations clearly (ADR-004).
  • If critical bugs are found, vendor-fork as a last resort.

Test Plan

  • PTY tests validate cleanup on normal exit and panic.
  • CI includes Linux, macOS, and Windows builds.
  • Integration tests exercise resize and input events.
  • Manual testing on common terminals (see terminal compatibility).

Implementation

See crates/ftui-core/src/terminal_session.rs for the TerminalSession wrapper that provides the one-writer-rule-compliant API with guaranteed cleanup.

See Also