osteak
Elm for ratatui — you bring the loop.
Why osteak?
Every ratatui app that grows past demo complexity hits the "bag of booleans" wall — state scattered across fields, implicit transitions, race conditions when async work outlives UI signals.
| osteak | ratatui-elm | teatui | tui-realm | |
|---|---|---|---|---|
| ratatui 0.30 | yes | no (0.29) | no (0.29) | no (0.29) |
| You keep event loop | yes | no | no | no |
&mut update (no clone) |
yes | yes | no | n/a |
Full Frame access |
yes | yes | no | yes |
| Async task integration | yes | no | own runtime | n/a |
| Dirty tracking | yes | no | no | no |
Quick Start
use ;
use Frame;
use Paragraph;
With the built-in runner
use ;
async
Without the runner
You always have the option to write your own event loop — osteak never takes
control away. See examples/counter_manual.rs.
Architecture
┌──────────────────────┐
│ Your Event Loop │
│ (or osteak::runner) │
└──────┬───────────────┘
│ Msg
┌──────▼───────────────┐
│ Tea::update(&mut) │
│ → Cmd { action, │
│ dirty } │
└──────┬───────────────┘
│
┌────────────┼────────────┐
│ │ │
Action::Task Action::None Action::Quit
(you spawn) (no-op) (exit loop)
│
│ Msg (on completion)
└──────────► back to update
Features
| Feature | Default | Description |
|---|---|---|
crossterm-backend |
yes | Crossterm terminal backend + EventStream |
tokio-runtime |
yes | Tokio integration for the runner module |
To use osteak without the runner (just the traits):
Examples
counter— minimal app with the built-in runnercounter_manual— same app, hand-written event loopasync_tasks—Cmd::taskwithtokio::spawnin a manual loopmulti_pane— model composition withCmd::map
MSRV
The minimum supported Rust version is 1.86.0 (same as ratatui 0.30).
License
Contributing
See CONTRIBUTING.md.