Skip to main content

Crate tuika

Crate tuika 

Source
Expand description

tuika — the application framework for Rust terminal UIs, built over ratatui.

Where ratatui owns the cell buffer and the widgets drawn into it, tuika owns the layer an application needs above that, so a TUI starts as a described screen rather than a render loop.

tuika adds the pieces ratatui leaves to you — a flexbox-style layout solver, anchored overlays, focus/input-ownership, a host for either screen mode (alternate screen or a split footer over live terminal scrollback), and a set of components (text, boxes, scroll, select, spinner, progress) — while letting ratatui keep ownership of the cell buffer and its diff against the terminal. It builds against ratatui-core (and ratatui-crossterm for the backend) directly rather than the ratatui umbrella — it renders none of ratatui’s own widgets — so ratatui-widgets and ratatui-macros stay out of its dependency tree. It otherwise depends only on crossterm, textwrap, unicode-segmentation, and unicode-width.

It was extracted from the yolop coding agent, whose full-screen renderer is built on it, but it knows nothing about any host application.

§Model

  • Views (view::View) are ephemeral, rebuilt from application state each frame; ratatui diffs the resulting cell buffer, so this is cheap.
  • State that must persist across frames (components::ScrollState, components::SelectState, focus::FocusRegistry) lives in the host, in the StatefulWidget idiom.
  • Layout is a flexbox subset (layout); overlays (overlay) anchor over the base tree; the host (host) owns the screen (screen::ScreenMode — the alternate screen, or a split footer over live terminal scrollback), translates crossterm input, and composites the frame.
  • Scene composition is owned with Scene, or borrows a host-state view for one frame with ScopedScene; both use the same ordered overlay and focus semantics.

§Finding things

The crate root re-exports the framework: the view model, layout, events, styling, and the host seam — the types you compose with. The widgets themselves live in components. Owned Element trees use Scene; a concrete root that borrows large application state uses ScopedScene without cloning it. Everything that talks to the terminal outside the cell grid (clipboard, hyperlinks, images, native progress, capability detection) lives in term.

For application code that wants the common surface in one line, glob-import prelude:

use tuika::prelude::*;

let screen = element(Flex::column().fixed(1, element(Text::raw("hello"))));

§Extending

Add a component by implementing view::View in a new module under components. No registration step; containers accept any boxed View.

Existing ratatui widgets should normally be wrapped in RatatuiView, which preserves Tuika clipping without exposing the frame buffer. TerminalSession and runner::Runner are optional host-side lifecycle helpers; with feature = "async", runner::AsyncRunner is the same loop for hosts that already run on Tokio.

Re-exports§

pub use event::Event;
pub use event::EventFlow;
pub use event::Key;
pub use event::KeyCode;
pub use event::Mouse;
pub use event::MouseButton;
pub use event::MouseKind;
pub use geometry::Padding;
pub use geometry::Size;
pub use host::TerminalSession;
pub use host::paint;
pub use host::paint_scene;
pub use host::paint_with_sheet;
pub use host::translate_event;
pub use layout::Align;
pub use layout::Dimension;
pub use layout::Direction;
pub use layout::Justify;
pub use layout::LayoutStyle;
pub use overlay::Overlay;
pub use overlay::OverlaySpec;
pub use runner::AsyncRunner;async
pub use runner::Signal;async
pub use runner::Runner;
pub use runner::RunnerConfig;
pub use scene::Backdrop;
pub use scene::Scene;
pub use scene::SceneOverlay;
pub use scene::ScopedScene;
pub use screen::ScreenMode;
pub use screen::Scrollback;
pub use style::SemanticRole;
pub use style::StyleSheet;
pub use style::Theme;
pub use surface::Surface;
pub use view::Element;
pub use view::RenderCtx;
pub use view::View;
pub use view::element;

Modules§

anim
Animation helpers: easing curves and a frame phase.
components
Component library.
event
Input events, decoupled from crossterm.
focus
Focus registry and input ownership.
framebuffer
FrameBuffer — a mutable RGBA canvas with sprite blitting and per-pixel shaders, rendered to cells with half-blocks.
geometry
Geometry helpers shared across tuika.
highlight
The Highlighter seam — how a host plugs syntax highlighting into CodeBlock and Markdown without tuika taking on any grammar dependency.
host
Terminal host: screen-mode lifecycle, event translation, compositor.
interop
Safe interoperability with ratatui widgets.
keymap
A host-agnostic keymap engine: declarative key bindings resolved to named commands, with layered scoping, mode gating, and multi-stroke sequences.
layout
Flexbox-style layout solver.
live
Small observable values for data-driven views.
mouse
Mouse interaction over the rendered cell grid: text selection, click hit-testing, and click detection.
overlay
Overlay positioning (Pi’s overlay model).
prelude
The common surface in one import.
probe
Reading laid-out rects back out of the view tree.
runner
Small full-screen run loops.
scene
Owned and borrowed base-tree composition with owned overlays.
screen
Screen modes: which part of the terminal a tuika frame owns.
style
Styling and theming.
surface
Clipped drawing surface over a ratatui Buffer.
term
Terminal capabilities that live outside the cell grid.
testing
Public helpers for hermetic view and resize tests.
themes
Bundled standard themes.
view
The View trait — the extensibility seam for components.
width
Grapheme-aware display-width measurement.

Macros§

view
Build a tuika Element tree from a declarative, top-down layout description.