Skip to main content

Comparison with other TUI frameworks

Verum's TUI stack is a late-comer to an industry with mature options. It borrows freely from all of them, and differs in a few opinionated ways.

At a glance

AspectVerum core.termRatatui (Rust)Textual (Python)Ink (Node)Bubble Tea (Go)
ArchitectureTEA — ElmImmediateReactive / CSSReact + hooksTEA — Elm
RenderingDouble-buffer + diff + row-skip + sync-outputDouble-buffer + diffDiff + dirty regionsVDOM diffDouble-buffer + diff
LayoutConstraint + Flex + GridConstraint onlyCSS Grid / FlexYoga flexLip Gloss manual
Widgets20 built-in~20~40~15 via Ink UIBubbles set (~15)
AsyncCommand.task(future) nativetokio you wire yourselfasync def, nativeasync/awaittea.Cmd = func() Msg
SubscriptionsFirst-class SubscriptionManualCSS watchers, reactiveuseEffecttea.Sub (deprecated — now Cmd)
CancellationStructured, automaticManualAutomaticManualManual
UnicodeGrapheme-aware; ZWJ emoji, flagsVia unicode-widthFullFullrunewidth
MouseSGR 1006SGR 1006SGR 1006SGR 1006SGR 1006
GraphicsKitty + Sixel + iTerm2 + Braille fallbackVia third-partyLimitedNoNo
ClipboardOSC 52 built-inVia third-partyVia pyperclipclipboardyclipboard-go
AccessibilityOSC 133 zonesNoPartialNoNo
Colour profileAuto-detect + CIELAB downsamplingAuto-detect (naive)CSS variablesTruecolor onlyAuto-detect
TestingPure update, snapshot BufferMock terminalpytest snapshotsink-testing-libraryModel testing

What Verum does better

  • Out-of-box graphics. Kitty + Sixel + iTerm + Braille fallback is one function call (create_graphics_renderer(caps, writer)).
  • Structured async. Command.task(future) is spawned on the same runtime that backs core.async; cancellation is wired automatically.
  • Perceptual colour adaptation. CIELAB distance gives the right fallback on 16-colour shells; naive RGB distance (Ratatui, Bubble Tea) does not.
  • Full Flex + Grid. Ratatui ships only Constraint; Verum has CSS Flex Level 1 plus CSS Grid Level 1 with fr units and minmax().
  • Strong typing end-to-end. Verum's Command<Msg> is parameterised; Bubble Tea's is func() tea.Msg with interface{} payloads.

What Textual does better (today)

  • Declarative CSS. Textual's TCSS is the most ergonomic terminal styling language. Verum's Theme + Style builder is equivalent in expressive power but not in terseness for static skins. This is on the roadmap — see the theming guide.
  • 40+ widgets. Textual's widget library is the biggest in the industry. Verum ships 20 production-grade widgets; most missing ones (DataTable, Switch, TabbedContent, Markdown, DirectoryTree) can be assembled from existing primitives in < 200 lines.
  • Web deployment. Textual apps can run in a browser via textual serve. Verum's path here goes through WASM + xterm.js; not yet shipped.

What Ink/React-style does better

  • Component reuse. React hooks make per-widget state trivial to share between components. Verum's StatefulWidget with an associated State type is equivalent but more boilerplate.

Migration notes

  • From Ratatui. The rendering layer (Buffer, Frame, Widget) is almost 1:1 — Cell, set_string, set_style, get_mut — so porting widgets is mostly a syntax exercise. The app layer is different (TEA vs immediate); but if your Ratatui app used tokio + a state machine you're halfway to TEA already.
  • From Bubble Tea. The Elm architecture maps straight across. tea.CmdCommand; tea.SubSubscription; tea.Model.UpdateModel.update; tea.Model.ViewModel.view. The biggest difference: Verum commands are typed by Msg, not interface{}.
  • From Textual. Reactive attributes become explicit Msg transitions in update. CSS rules become Theme + Style at render time. Timer watchers become Subscription.interval.