# Ratatui — Terminal User Interface Library for Rust > Ratatui is a Rust library for building rich terminal user interfaces (TUIs). It provides widgets for tables, charts, lists, paragraphs, tabs, and more — enabling you to build beautiful, interactive terminal applications with immediate-mode rendering. ## Install Save as a script file and run: # Ratatui — Terminal User Interface Library for Rust ## Quick Use ```bash # Add Ratatui to your Rust project cargo add ratatui crossterm ``` ```rust use ratatui::{ crossterm::event::{self, Event, KeyCode}, layout::{Constraint, Layout}, style::{Color, Style}, widgets::{Block, Borders, Paragraph}, DefaultTerminal, }; fn main() -> Result<(), Box> { let mut terminal = ratatui::init(); loop { terminal.draw(|frame| { let area = frame.area(); let block = Block::default() .title(" My App ") .borders(Borders::ALL) .style(Style::default().fg(Color::Cyan)); let paragraph = Paragraph::new("Hello, Ratatui!") .block(block); frame.render_widget(paragraph, area); })?; if matches!(event::read()?, Event::Key(k) if k.code == KeyCode::Char('q')) { break; } } ratatui::restore(); Ok(()) } ``` ## Introduction Ratatui is a community fork of tui-rs that has become the standard library for building terminal UIs in Rust. It uses an immediate-mode rendering approach — you describe what the UI should look like each frame, and Ratatui efficiently diffs and updates only what changed. This makes building complex, interactive TUIs surprisingly straightforward. With over 20,000 GitHub stars, Ratatui powers popular tools like gitui, bottom, kdash, and many other terminal applications. It is the Rust equivalent of Bubble Tea for Go. ## What Ratatui Does Ratatui provides a layout system (constraints-based, like CSS Flexbox) and a rich set of widgets (paragraphs, lists, tables, charts, gauges, tabs, etc.). You compose layouts and widgets each frame, and Ratatui handles terminal manipulation, color rendering, and efficient screen updates via crossterm or termion backends. ## Architecture Overview ``` [Your Application] State + event handling | [Ratatui] Layout + Widgets | +-------+-------+ | | | [Layout] [Widgets] Constraint Paragraph Direction List, Table Rect Chart, Gauge Margin Tabs, Block | [Terminal Backend] crossterm (cross-platform) or termion (Unix) | [Terminal Emulator] Renders ANSI escape codes ``` ## Self-Hosting & Configuration ```rust use ratatui::{ layout::{Constraint, Direction, Layout}, style::{Color, Modifier, Style}, widgets::{Block, Borders, List, ListItem, Paragraph, Gauge}, DefaultTerminal, Frame, }; struct App { items: Vec, selected: usize, progress: f64, } fn ui(frame: &mut Frame, app: &App) { let chunks = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Length(3), Constraint::Min(5), Constraint::Length(3), ]) .split(frame.area()); // Title let title = Paragraph::new("Dashboard") .style(Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)) .block(Block::default().borders(Borders::ALL)); frame.render_widget(title, chunks[0]); // List let items: Vec = app.items.iter() .enumerate() .map(|(i, item)| { let style = if i == app.selected { Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD) } else { Style::default() }; ListItem::new(item.as_str()).style(style) }) .collect(); let list = List::new(items) .block(Block::default().title(" Items ").borders(Borders::ALL)); frame.render_widget(list, chunks[1]); // Progress bar let gauge = Gauge::default() .block(Block::default().title(" Progress ").borders(Borders::ALL)) .gauge_style(Style::default().fg(Color::Green)) .ratio(app.progress); frame.render_widget(gauge, chunks[2]); } ``` ## Key Features - **Rich Widgets** — Paragraph, List, Table, Chart, Gauge, Tabs, Sparkline - **Layout System** — constraint-based layouts (like Flexbox) - **Styling** — colors, bold, italic, underline, and 256/RGB colors - **Immediate Mode** — describe UI each frame, Ratatui handles diffing - **Backend Agnostic** — crossterm (cross-platform) or termion (Unix) - **Composable** — nest layouts and widgets freely - **Scrolling** — built-in scroll state for lists, tables, and text - **Custom Widgets** — implement the Widget trait for custom components ## Comparison with Similar Tools | Feature | Ratatui | Bubble Tea (Go) | Textual (Python) | ncurses | Ink (React) | |---|---|---|---|---|---| | Language | Rust | Go | Python | C | JavaScript | | Paradigm | Immediate mode | Elm architecture | Widget tree | Procedural | React components | | Widgets | Rich built-in | Bubbletea + Bubbles | Rich built-in | Low-level | React-style | | Cross-Platform | Yes (crossterm) | Yes | Yes | Unix-focused | Yes | | Performance | Excellent | Excellent | Good | Excellent | Moderate | | Best For | Rust TUIs | Go TUIs | Python TUIs | C/C++ TUIs | JS TUIs | ## FAQ **Q: Ratatui vs tui-rs — what happened?** A: Ratatui is a community fork of tui-rs after the original maintainer stepped back. Ratatui is actively maintained with frequent releases and new features. Always use Ratatui for new projects. **Q: How does immediate-mode rendering work?** A: Each frame, you describe the entire UI from scratch. Ratatui compares the new frame with the previous one and only sends the differences to the terminal. This makes UI code simple — no manual state tracking for what changed. **Q: Can I use Ratatui for production tools?** A: Yes. Tools like gitui (Git TUI), bottom (system monitor), and kdash (Kubernetes dashboard) use Ratatui in production with thousands of users. **Q: How do I handle user input?** A: Use crossterm events (event::read()) in your main loop. Match on KeyCode, MouseEvent, or Resize. Ratatui does not handle input — it only renders. ## Sources - GitHub: https://github.com/ratatui/ratatui - Documentation: https://ratatui.rs - Examples: https://github.com/ratatui/ratatui/tree/main/examples - Community fork of tui-rs - License: MIT --- Source: https://tokrepo.com/en/workflows/82197cf0-3745-11f1-9bc6-00163e2b0d79 Author: Script Depot