| Crates.io | tuyere |
| lib.rs | tuyere |
| version | 0.1.0 |
| created_at | 2025-12-14 19:06:55.264696+00 |
| updated_at | 2025-12-14 19:06:55.264696+00 |
| description | A powerful TUI framework based on The Elm Architecture 🔮 |
| homepage | https://molten.dev |
| repository | https://github.com/moltenlabs/tuyere |
| max_upload_size | |
| id | 1984937 |
| size | 51,368 |
A powerful TUI framework based on The Elm Architecture.
A tuyere is the nozzle that feeds air into a forge, bringing it to life. This crate does the same for your terminal apps—feeding events through the Elm Architecture to create beautiful, reactive TUIs.
use tuyere::{App, Model, Command, Event, Key};
struct Counter { count: i32 }
enum Msg { Increment, Decrement, Quit }
impl Model for Counter {
type Message = Msg;
fn update(&mut self, msg: Msg) -> Command<Msg> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Msg::Quit => return Command::quit(),
}
Command::none()
}
fn view(&self) -> String {
format!("Count: {}\n\nPress +/- to change, q to quit", self.count)
}
fn handle_event(&self, event: Event) -> Option<Msg> {
match event {
Event::Key(Key::Char('+')) => Some(Msg::Increment),
Event::Key(Key::Char('-')) => Some(Msg::Decrement),
Event::Key(Key::Char('q')) => Some(Msg::Quit),
_ => None,
}
}
}
fn main() {
App::new(Counter { count: 0 }).run().unwrap();
}
Model and you're doneglyphs and lacquercargo add tuyere
Part of the Molten Labs open source ecosystem:
| Crate | Description |
|---|---|
| molten_brand | Design tokens & colors |
| glyphs | ANSI escape sequences |
| lacquer | Terminal styling |
| tuyere | TUI framework (you are here) |
| scoria | TUI components |
| chant | Shell glamour |
| aglow | Markdown renderer |
| censer | Pretty logging |
MIT OR Apache-2.0
Built with 🔮 by Molten Labs