Skip to main content

Crate osteak

Crate osteak 

Source
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.