Expand description
§osteak — Elm for ratatui
You bring the loop. osteak brings the structure.
§The Problem
Every ratatui app that grows past demo complexity hits the “bag of booleans” wall. State scatters across fields, transitions become implicit, and race conditions emerge when async work outlives UI signals.
§The Solution
osteak brings the Elm Architecture to ratatui:
- Model — your application state (the struct implementing
Tea) - Message — an enum of everything that can happen (
Tea::Msg) - Update — process a message, mutate state, return a
Cmd - View — render the current state to a ratatui
Frame
§You Keep Your Event Loop
osteak does not own your event loop. You call Tea::update and
Tea::view when you want. This lets you integrate with any async
runtime, any event source, any rendering strategy.
For simple apps, the optional runner module provides a ready-made
event loop powered by crossterm and tokio.
§Quick Start
use osteak::{Tea, Cmd, Action};
use ratatui::Frame;
use ratatui::widgets::Paragraph;
struct Counter { count: i32 }
enum Msg { Increment, Decrement, Quit }
impl Tea for Counter {
type Msg = Msg;
fn update(&mut self, msg: Msg) -> Cmd<Msg> {
match msg {
Msg::Increment => { self.count += 1; Cmd::dirty() }
Msg::Decrement => { self.count -= 1; Cmd::dirty() }
Msg::Quit => Cmd::quit(),
}
}
fn view(&mut self, frame: &mut Frame) {
let text = format!("Count: {}", self.count);
frame.render_widget(Paragraph::new(text), frame.area());
}
}Modules§
- runner
- Optional runner — a convenience for simple TEA apps.
Structs§
- Cmd
- The result of processing a message in
Tea::update. - Sub
- A subscription to an external event source.
Enums§
- Action
- A side effect to perform after an update.
Traits§
- Tea
- The core TEA trait. Implement this on your application state.