Choosing a TUI framework

Choose the model you want to build with.

Language, state ownership, and deployment shape a project more than a row of checkmarks. Here is how five frameworks approach them.

Sources reviewed . SwiftTUI examples use 0.14.0; other entries describe the linked project documentation at review time.

Swift

SwiftTUI

A fit for apps that benefit from SwiftUI-style view composition, tracked state, and shared views across hosts.

UI model
Declarative views, state and observation; the runtime owns layout and redraw.
Terminal platforms
macOS 15+, Linux, and Windows 10 1809+ / Server 2019+. Swift 6.4 toolchain.
Input
Focus traversal, keyboard commands, and tap, drag, and hover gestures. Terminal mouse support is negotiated.
Motion
Built-in state animation, withAnimation, and phase animation. Terminal rendering remains cell-based.
Browser
Compile with SwiftTUIWASI and serve a static bundle with @swifttui/web. The browser runs the app.
Native apps
SwiftUIHost embeds views in macOS and iOS. Android arm64 is a preview with documented limitations.

Go

Bubble Tea

A fit for Go applications organized around messages, an update function, and a view of the model.

UI model
The Elm Architecture: a model, Update for incoming messages, and View for output. Bubble Tea handles redraw.
Terminal platforms
Cross-platform terminal applications; check the project’s platform-specific implementation and your target terminal.
Input
Keyboard and mouse messages. Bubbles supplies reusable controls; gesture behavior can be composed by the application.
Motion
Timed updates in the app; the companion Harmonica package supplies spring animation.
Browser
The linked core documentation describes a terminal renderer, not a bundled static browser host.
Native apps
No SwiftUI-style native embedding host is documented in the linked core sources. Integration requires additional work.

Python

Textual

A fit for Python applications with a widget tree, CSS layout and styling, and reactive properties.

UI model
Composed widgets, reactive attributes, events, and CSS for layout and presentation.
Terminal platforms
Linux, macOS, and Windows, using a supported Python environment.
Input
Keyboard focus, bindings, and mouse events including movement and clicks.
Motion
Built-in animation of numeric values, colors, and styles, with easing.
Browser
textual-serve runs the Python application on a server and connects a browser over WebSockets. It is not a static WASM bundle.
Native apps
The linked project documents terminal and browser delivery; a native app wrapper is a separate integration.

Rust

Ratatui

A fit for Rust applications that want direct control over rendering, state management, and event handling.

UI model
Immediate-mode rendering with widgets and constraint-based layout. The application chooses its state and event architecture.
Terminal platforms
Platform support depends on the chosen terminal backend; Crossterm is the common cross-platform choice.
Input
Events come from the backend or an input library. The app routes them to its state and controls.
Motion
Application-driven frame updates; the companion tachyonfx crate provides effects and animation.
Browser
The separate Ratzilla project provides web backends for Rust/WASM applications built with Ratatui.
Native apps
Alternate backends and embedding are possible; native integration is not the same contract as SwiftUIHost.

JavaScript / TypeScript

Ink

A fit for command-line tools that use React components, hooks, and the Node.js ecosystem.

UI model
A React renderer for terminal output, with Yoga-based flexbox layout.
Terminal platforms
Runs in Node.js. Verify the supported Node version and terminal behavior for your deployment targets.
Input
Keyboard input and focus hooks. Mouse gestures are not presented as a core API in the linked documentation.
Motion
useAnimation provides a shared timer, frame count, elapsed time, and delta. The application defines interpolation or frame content.
Browser
React familiarity does not make the Ink renderer a browser renderer; no static browser host is documented in the core README.
Native apps
Ink targets terminal output. React Native is a different renderer and is not an Ink embedding host.

Reading the comparison

Built-in, companion, and custom are different choices.

A companion package can be the right tool. A capability not documented in the linked core sources may still be available elsewhere in its ecosystem.

Browser hosting also has different meanings: serving a process over a connection and running a static WebAssembly bundle have different deployment requirements. Platform support does not imply identical behavior in every terminal. Check the linked requirements against your application.