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
  • 4 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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.