Skip to content
Back to skills

Ratatui

ASecurity

Build terminal UIs in Rust with Ratatui. Use when creating TUI applications, immediate-mode rendering, high-performance terminal interfaces, or production Rust CLIs.

  • 94 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 28, 2026
developmentrustgobashbackendperformance

Works with

  • terminal
  • cli

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned May 28, 2026

npx -y skills add FlorianBruniaux/ccboard --skill ratatui --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ratatui?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ratatui
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/florianbruniaux-ratatui/badge)](https://www.skillsdirectory.com/skills/florianbruniaux-ratatui)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ratatui
description: Build terminal UIs in Rust with Ratatui. Use when creating TUI applications, immediate-mode rendering, high-performance terminal interfaces, or production Rust CLIs.
effort: medium
allowed-tools: Read, Write, Edit, Bash, Grep
---

# Ratatui (Rust TUI)

Immediate-mode terminal UI framework for Rust using Crossterm backend.

## When to Use

- Creating a new TUI application from scratch in Rust
- Adding an interactive terminal interface to an existing CLI tool
- Implementing tabbed navigation, lists, tables, or charts in the terminal
- High-performance terminal rendering where latency matters (e.g., monitoring dashboards)

**Keywords**: TUI, terminal UI, ratatui, crossterm, interactive CLI, dashboard, ncurses alternative

## Workflow

1. **Add dependencies** to `Cargo.toml` (ratatui + crossterm)
2. **Define App state struct** — holds all mutable data (selected index, input buffer, etc.)
3. **Initialize terminal** — enable raw mode, enter alternate screen
4. **Main event loop** — `terminal.draw(|f| ui(f, &app))` + `event::poll` + key handler
5. **Build UI function** — `Layout::split` → assign chunks → `render_widget` per chunk
6. **Teardown** — disable raw mode, leave alternate screen on exit or panic

## Dependencies

```toml
[dependencies]
ratatui = "0.28"
crossterm = "0.28"
```

## Basic Application

```rust
use crossterm::{
    event::{self, Event, KeyCode},
    execute,
    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{backend::CrosstermBackend, widgets::{Block, Borders, Paragraph}, Terminal};
use std::io;

struct App {
    counter: i32,
}

impl App {
    fn new() -> App {
        App { counter: 0 }
    }

    fn on_key(&mut self, key: KeyCode) {
        match key {
            KeyCode::Up => self.counter += 1,
            KeyCode::Down => self.counter -= 1,
            _ => {}
        }
    }
}

fn main() -> Result<(), io::Error> {
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen)?;

    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    let mut app = App::new();

    loop {
        terminal.draw(|f| {
            let block = Block::default().title("Counter").borders(Borders::ALL);
            let paragraph = Paragraph::new(format!("Count: {}", app.counter)).block(block);
            f.render_widget(paragraph, f.area());
        })?;

        if let Event::Key(key) = event::read()? {
            match key.code {
                KeyCode::Char('q') => break,
                code => app.on_key(code),
            }
        }
    }

    disable_raw_mode()?;
    execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
    Ok(())
}
```

## Event Loop with Polling

```rust
use std::time::Duration;

fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<()> {
    loop {
        terminal.draw(|f| ui(f, app))?;

        if event::poll(Duration::from_millis(100))? {
            if let Event::Key(key) = event::read()? {
                match key.code {
                    KeyCode::Char('q') => return Ok(()),
                    KeyCode::Up => app.increment(),
                    KeyCode::Down => app.decrement(),
                    _ => {}
                }
            }
        }
    }
}
```

## Layout

```rust
use ratatui::layout::{Constraint, Direction, Layout};

let chunks = Layout::default()
    .direction(Direction::Vertical)
    .constraints([
        Constraint::Length(3),  // Fixed height
        Constraint::Min(0),     // Fill remaining
        Constraint::Length(1),  // Status bar
    ])
    .split(f.area());
```

## References

- **Widgets**: See [references/widgets.md](references/widgets.md) for List, Table, Paragraph, Gauge
- **Best Practices**: See [references/best-practices.md](references/best-practices.md) for keyboard, accessibility, performance

Files in this skill

  • SKILL.md3.9 KB
  • references/best-practices.md4 KB
  • references/widgets.md3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…