Ratatui: Cooking Up Terminal UIs in Rust
If you've ever wanted to build a terminal user interface (TUI) in Rust, you've probably run into tui-rs — the go-to crate for drawing boxes, text, and widgets in your terminal. Well, tui-rs has been forked and reborn as Ratatui, a community-driven project that keeps the same solid API but adds active maintenance, fresh features, and a friendlier vibe.
Think of it as the Ratatouille of Rust TUI libraries — simple ingredients, flexible recipes, and surprisingly elegant results.
What It Does
Ratatui is a Rust crate that lets you build interactive terminal applications with a declarative approach. You define layouts, widgets (like paragraphs, tables, lists, charts), and handle input events. It handles all the low-level terminal rendering, so you can focus on what your app looks like and how it behaves.
Under the hood, it uses a buffered rendering approach: you build up a virtual "frame" of styled text and unicode blocks, then flush it to the terminal in one efficient pass. This means smooth updates, minimal flicker, and support for colors, bold, italic, and even custom unicode characters.
Why It's Cool
- Active maintenance — the original
tui-rshasn't seen a release in years. Ratatui is now the de facto maintained version with regular updates, bug fixes, and new features. - Backward compatible — if you have existing
tui-rscode, dropping in Ratatui usually just works. The team made sure to keep the API familiar. - Rich widget library — tables, paragraphs, lists, gauges, sparklines, block borders, and more. You can even build custom widgets by implementing the
Widgettrait. - Flexible layout — use
Constraint::Length,Constraint::Percentage, orConstraint::Min/Maxto split your terminal into rows and columns, then nest layouts however you like. - Excellent async support — works great with
tokio,async-std, or any async runtime. Just spawn your event loop and render in a background task. - No external dependencies for rendering — the crate only needs a terminal backend (like
crossterm,termion, ortermwiz). You pick your poison.
How to Try It
Add Ratatui to your Cargo.toml:
[dependencies]
ratatui = "0.25"
crossterm = "0.27"
Then fire up a basic example. Here's a minimal counter app that prints a number and increments on keypress:
use ratatui::{prelude::*, widgets::*};
use crossterm::event::{self, Event, KeyCode};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut terminal = Terminal::new(CrosstermBackend::new(std::io::stdout()))?;
terminal.clear()?;
let mut counter = 0;
loop {
terminal.draw(|frame| {
let area = frame.size();
let text = format!("Counter: {}", counter);
let paragraph = Paragraph::new(text).block(Block::default().borders(Borders::ALL).title("Counter App"));
frame.render_widget(paragraph, area);
})?;
if let Event::Key(key) = event::read()? {
match key.code {
KeyCode::Char('q') => break,
KeyCode::Up => counter += 1,
KeyCode::Down => counter -= 1,
_ => {}
}
}
}
terminal.clear()?;
Ok(())
}
Run it:
cargo run
Press Up to increment, Down to decrement, and q to quit.
For more, check out the official examples in the repo — there are dozens covering everything from progress bars to chat UIs.
Final Thoughts
Ratatui is one of those libraries that just works. It doesn't try to be a framework — it's a toolbox. You can build full terminal apps (think htop, lazygit, or spotify-tui) with it, or just add a simple interactive widget to a CLI tool.
If you're already using tui-rs, the migration is painless. If you're new to terminal UIs in Rust, this is the best place to start. The documentation is solid, the community is active, and the crate is under active development — no more worrying about stale dependencies.
So go ahead, cook something up in your terminal. Ratatui makes it surprisingly fun.
This post was curated from @githubprojects
Repository: https://github.com/ratatui-org/ratatui