ADR-003: Ratatui as the TUI rendering library
Why jackin' uses ratatui and not tui-rs, crossterm-raw, or another terminal rendering approach.
Status: Accepted
Current state: ratatui 0.30 used across all three TUI surfaces. SocketBackend custom backend in jackin-capsule for attach-socket rendering (see ADR-004).
Date: 2026-05-30
Deciders: Operator + agent
Context
jackin' needs to render full-screen terminal UIs on three surfaces: the host workspace console (jackin-console), the launch progress cockpit (jackin-launch), and the in-container multiplexer (jackin-capsule). The choices at the time of evaluation were:
tui-rs— the original Rust immediate-mode TUI library. Archived/abandoned in 2023.ratatui— a community fork oftui-rs, actively maintained as its de-facto successor.- Raw ANSI/crossterm — write escape sequences directly; maximum control, no widget abstraction.
cursive— retained-mode widget library; richer widget tree but heavier, less composable.
Decision
Use ratatui as the primary TUI rendering library across all three surfaces.
ratatui is pinned at 0.30 per-crate in each consuming crate — crates/jackin-tui/Cargo.toml, crates/jackin-capsule/Cargo.toml, crates/jackin-console/Cargo.toml, crates/jackin-launch/Cargo.toml, and crates/jackin-tui-lookbook/Cargo.toml:
ratatui = "0.30"Why ratatui over tui-rs: tui-rs is archived. ratatui is the fork that the tui-rs maintainer and the broader community adopted as the continuation. All active development, bug fixes, and new widget work happens in ratatui. Using tui-rs would mean no upstream fixes.
Why ratatui over raw ANSI everywhere: Raw ANSI gives byte-level control but requires hand-rolling layout, clipping, UTF-8 display-width, scrollbar geometry, and double-buffered diffing. ratatui handles all of that through its Buffer/Rect/Widget model, which is composable and testable via TestBackend. The capsule now renders pane body content from jackin-term snapshots through PaneBodyWidget (see ADR-004), while chrome, dialogs, and overlays also use ratatui.
Why ratatui over cursive: cursive is retained-mode (a widget tree you mutate) versus ratatui's immediate-mode (render from state every frame). Immediate-mode pairs directly with the Elm Architecture adopted across all jackin' TUI surfaces: state → render, no widget identity to track. ratatui also has a much larger and more active ecosystem of third-party widgets and examples.
Consequences
- All three surfaces share the same rendering primitives,
Rect/Layout/Block/Paragraph/Widgetmodel, andTestBackendfor snapshot tests. - The shared
jackin-tuicrate owns cross-surface components;ratatuitypes flow through its public API, makingratatuian intentional public dependency. - The capsule uses a custom
SocketBackendthat serialisesBuffer::diffoutput over the attach socket (see ADR-004); this is possible becauseratatui's backend trait is open. - Major
ratatuiversion bumps require auditing widget API changes across all three surfaces. The matching per-crate0.30pins keep every crate on the same version. ratatuiis pre-1.0 but is the canonical active successor totui-rswith broad ecosystem adoption; the pre-1.0 API instability is acceptable given the lack of maintained alternatives.