本文へ移動
cccskills
無料GitHub で公開

ratatui

Use when building terminal user interfaces in Rust with the ratatui crate - layout system, widget usage, input/event handling, app state architecture, TUI testing, or migrating between ratatui 0.29 and 0.30

インストール方法を見る

含まれるファイル(6)

  • SKILL.md9.8 KB
  • references/architecture.md8.6 KB
  • references/ecosystem.md8.6 KB
  • references/recipes.md7.5 KB
  • references/testing.md1.3 KB
  • references/widgets.md10.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Ratatui

Rust terminal UI framework for building interactive command-line applications.

Overview

Ratatui provides widgets, layout systems, event handling, and rendering for TUI apps.

Key Features:

  • Multiple layout systems (blocks, flex, horizontal, vertical)
  • Built-in widgets (buttons, checkboxes, tables, charts)
  • Event-driven input handling with keyboard and mouse support
  • Multiple backends (crossterm, termion, termwiz)
  • no_std support for embedded targets

Installation

[dependencies]
ratatui = "0.30.1"

Feature Flags

ratatui = { version = "0.30.1", default-features = false, features = [
    "crossterm_0_28",  # Crossterm backend
    "layout-cache",    # Layout caching (default enabled)
    "palette",         # HSLuv color support
    "anstyle",         # anstyle conversions
] }

MSRV: 1.88.0 (v0.30.1)

Quick Start

use ratatui::{
    backend::CrosstermBackend,
    layout::{Constraint, Direction, Layout},
    style::{Color, Style},
    widgets::{Block, Borders, Paragraph},
    Frame, Terminal,
};
use std::io;

fn main() -> io::Result<()> {
    let backend = CrosstermBackend::new(io::stdout());
    let mut terminal = Terminal::new(backend)?;

    loop {
        terminal.draw(|f| {
            let chunks = Layout::default()
                .direction(Direction::Vertical)
                .constraints([Constraint::Length(3), Constraint::Min(0)])
                .split(f.area());

            let title = Paragraph::new("Hello, Ratatui!")
                .block(Block::bordered().title("Welcome"))
                .style(Style::default().fg(Color::Cyan));
            f.render_widget(title, chunks[0]);

            let instructions = Paragraph::new("Press 'q' to quit")
                .block(Block::bordered().title("Instructions"));
            f.render_widget(instructions, chunks[1]);
        })?;

        break;  // Add your event handling here
    }

    Ok(())
}

Layout System

Constraint Types

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

let chunks = Layout::default()
    .direction(Direction::Horizontal)
    .constraints([
        Constraint::Percentage(30),  // 30% of area
        Constraint::Length(50),      // 50 characters
        Constraint::Min(10),         // At least 10
        Constraint::Ratio(1, 4),     // 1/4 of remaining
    ])
    .split(area);

Flex Modes

use ratatui::layout::Flex;

// Center alignment
let chunks = Layout::default()
    .direction(Direction::Horizontal)
    .flex(Flex::Center)
    .constraints([Constraint::Length(20)])
    .split(area);

// SpaceEvenly - equal spacing including edges (v0.30+)
let chunks = Layout::default()
    .flex(Flex::SpaceEvenly)
    .constraints([Constraint::Length(20), Constraint::Length(20)])
    .split(area);

// SpaceAround - middle spacers twice the size of edges (v0.30+)
let chunks = Layout::default()
    .flex(Flex::SpaceAround)
    .constraints([Constraint::Length(20), Constraint::Length(20)])
    .split(area);

Overlapping Layouts

use ratatui::layout::Spacing;

// Overlap layouts by -1 spacing (useful for border overlap)
let chunks = Layout::default()
    .spacing(Spacing::Overlap)
    .constraints([Constraint::Length(3), Constraint::Length(3)])
    .split(area);

Ergonomic Rect Methods (v0.30+)

use ratatui::layout::Rect;

let centered = area.centered();                    // Both dimensions
let centered_h = area.centered_horizontally();
let centered_v = area.centered_vertically();
let outer = area.outer(Offset::new(1, 0));         // 1 cell to the right

// Split with compile-time array
let [left, right] = area.layout::<2>(Direction::Horizontal, &constraints);

Nested Layouts

let chunks = Layout::default()
    .direction(Direction::Vertical)
    .constraints([Constraint::Length(3), Constraint::Min(0)])
    .split(area);

let sub_chunks = Layout::default()
    .direction(Direction::Horizontal)
    .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
    .split(chunks[1]);

Widgets

See references/widgets.md for detailed widget recipes.

WidgetWhen to UseReference
ParagraphText display with styling/wrappingwidgets.md#paragraph
BlockFraming and titling other widgetswidgets.md#block
ButtonClickable buttons with pressed statewidgets.md#button
CheckboxBoolean toggle with custom symbolswidgets.md#checkbox
ListSelectable item listswidgets.md#list
TableTabular data with column selectionwidgets.md#table
GaugeProgress percentage displaywidgets.md#gauge
SparklineCompact data visualizationwidgets.md#sparkline
ChartMulti-dataset plots with axeswidgets.md#chart
CanvasCustom drawing with markerswidgets.md#canvas
CalendarDate display with Chronowidgets.md#calendar
FillPaint area with symbolwidgets.md#fill

Input Handling

Event Handling

use ratatui::event::{Event, EventHandler, KeyCode, KeyModifiers};

if let Some(Event::Key(key)) = handle_events(&mut handler) {
    match key.code {
        KeyCode::Char('q') => break,
        KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => break,
        KeyCode::Down | KeyCode::Char('j') => move_next(),
        KeyCode::Up | KeyCode::Char('k') => move_previous(),
        _ => {}
    }
}

Mouse Support

use ratatui::event::{Event, MouseEventKind};

if let Some(Event::Mouse(mouse)) = handle_events(&mut handler) {
    match mouse.kind {
        MouseEventKind::LeftClick => {
            // Handle click at mouse.column, mouse.row
        }
        MouseEventKind::ScrollDown => {
            // Handle scroll
        }
        _ => {}
    }
}

// Enable mouse capture
crossterm::execute!(stderr(), EnableMouseCapture)?;

State Management

See references/architecture.md for MVU/Flux patterns.

use ratatui::widgets::ListState;

struct AppState {
    items: Vec<String>,
    selected: usize,
    list_state: ListState,
}

impl AppState {
    fn new(items: Vec<String>) -> Self {
        let mut list_state = ListState::default();
        list_state.select(Some(0));
        Self { items, selected: 0, list_state }
    }

    fn next(&mut self) {
        if let Some(selected) = self.list_state.selected {
            let next = (selected + 1) % self.items.len();
            self.list_state.select(Some(next));
            self.selected = next;
        }
    }
}

Styling

use ratatui::style::{Color, Modifier, Style, Stylize};

let style = Style::default()
    .fg(Color::White)
    .bg(Color::Black)
    .add_modifier(Modifier::BOLD);

// Stylize trait (v0.30+)
let style = Style::new().blue().on_black().bold();
let styled: Text = "hello".yellow();

Color Types

Color::Reset        // Terminal default
Color::Red          // Basic terminal colors
Color::Rgb(255, 128, 0)  // True color
Color::Indexed(42)  // 256-color palette
Color::from_hsluv(Hsluv::new(0.0, 100.0, 50.0))  // HSLuv (requires "palette" feature)

Best Practices & Performance

Separate State from View

Keep state management separate from rendering logic. Use MVU pattern for predictable data flow.

Minimize Redraws

if app.state_changed {
    terminal.draw(|f| render_app(f, &app))?;
    app.state_changed = false;
}

Use Clear for Popups

Prevent content bleeding by clearing popup areas:

use ratatui::widgets::Clear;
Clear.render(popup_area, buf);

Handle Resize

use ratatui::event::Event;

if let Ok(Event::Resize(width, height)) = term.read_event() {
    term.resize(width, height)?;
}

Panic Recovery

std::panic::set_hook(Box::new(|_| {
    let _ = ratatui::restore();
}));

Breaking Changes: v0.29 → v0.30

ChangeMigration
Block::title() removedUse Block::new().title(Line::from("foo"))
block::Title deprecatedUse Line directly (removal in v0.31)
Style no longer implements StyledUse Style::new().blue() then widget.style(style)
Table::highlight_style() deprecatedUse table.row_highlight_style(...)
Marker is #[non_exhaustive]Use Marker::Custom('x') for custom markers
Backend requires Error typeAdd associated Error type to your backend
Rect::area() returns u32Update type expectations

Migration Example

// Old
Block::new().title("foo")

// New
Block::new().title(Line::from("foo").centered())

// Old
table.highlight_style(Style::default().fg(Color::Yellow))

// New
table.row_highlight_style(Style::default().fg(Color::Yellow))

Deep Dives

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

aiohttp

無料

Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

ast-grep

無料

Use when doing structural code search and rewriting - ast-grep linting, refactoring, multi-language patterns

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

Use when building GBA games with the BPCore Lua engine - entity, sprite and tilemap functions, SRAM save and load, link cable multiplayer protocol, camera and scrolling, or optimization patterns

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

celery

無料

Use when running background tasks with Celery - worker and broker configuration (Redis, RabbitMQ), task routing by name vs queue, chains/groups/chords, retry patterns (autoretry_for, retry_backoff), acks_late semantics, failure detection, and monitoring with Flower

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

django

無料

Use when building Django applications - security hardening, authentication and permissions, ORM optimization, PostgreSQL features, Django 6.0, migrations, testing, and ecosystem libraries

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

Use when customizing Django Admin - save_formset, get_search_results, formsets, queryset optimization, db_index, custom URLs

日本語の概要は準備中です。原文の説明を表示しています。

CodeAtCode/oss-ai-skills222026年10月9日 更新

CodeAtCode のスキルをすべて見る

このスキルの問題を報告する