Ratatui
GitHub概要
ratatui/ratatui
A Rust crate for cooking up terminal user interfaces (TUIs) 👨🍳🐀 https://ratatui.rs
ホームページ:https://ratatui.rs
スター14,115
ウォッチ44
フォーク440
作成日:2023年2月12日
言語:Rust
ライセンス:MIT License
トピックス
cliratatuirustterminalterminal-user-interfacetuiwidgets
スター履歴
データ取得日時: 2025/7/25 11:09
Ratatui
Ratatuiは、Rustでターミナルユーザーインターフェース(TUI)を構築するための最新かつ最も人気のあるライブラリです。tui-rsの精神的後継として、活発なコミュニティによって開発・保守されています。イミディエートモードレンダリングと豊富なウィジェットセットにより、美しく高性能なターミナルアプリケーションを作成できます。
特徴
イミディエートモードレンダリング
- フレームベース: 各フレームでUIを完全に再描画
- シンプルなAPI: 状態管理が直感的
- 高パフォーマンス: 最適化されたバッファリング
- 予測可能: 描画順序が明確
豊富なウィジェット
- 基本ウィジェット: Block、Paragraph、List、Table
- グラフ系: Chart、Sparkline、Gauge、BarChart
- レイアウト: Flexbox風のレイアウトシステム
- カスタムウィジェット: 独自ウィジェットの作成が容易
クロスプラットフォーム
- バックエンド対応: crossterm、termion、termwiz
- OS対応: Windows、macOS、Linux
- 非同期対応: async/await対応
- カラー対応: 16色、256色、RGB色
開発者体験
- 型安全: Rustの型システムを活用
- 優れたドキュメント: 包括的な例とガイド
- 活発なコミュニティ: 迅速なサポートと開発
- 豊富なサンプル: 実用的な例が多数
基本的な使用方法
インストール
[dependencies]
ratatui = "0.30"
crossterm = "0.27"
Hello World
use color_eyre::Result;
use crossterm::event::{self, Event};
use ratatui::{DefaultTerminal, Frame};
fn main() -> Result<()> {
color_eyre::install()?;
let terminal = ratatui::init();
let result = run(terminal);
ratatui::restore();
result
}
fn run(mut terminal: DefaultTerminal) -> Result<()> {
loop {
terminal.draw(render)?;
if matches!(event::read()?, Event::Key(_)) {
break Ok(());
}
}
}
fn render(frame: &mut Frame) {
frame.render_widget("hello world", frame.area());
}
レイアウトとウィジェット
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style, Stylize},
text::{Line, Span},
widgets::{Block, Borders, List, ListItem, Paragraph},
Frame,
};
fn ui(frame: &mut Frame) {
// レイアウトを作成
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3),
Constraint::Min(0),
Constraint::Length(3),
])
.split(frame.area());
// ヘッダー
let header = Paragraph::new("My TUI Application")
.block(Block::default().borders(Borders::ALL))
.style(Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD));
frame.render_widget(header, chunks[0]);
// メインコンテンツ
let items = vec![
ListItem::new("Item 1"),
ListItem::new("Item 2").style(Style::default().fg(Color::Yellow)),
ListItem::new("Item 3"),
];
let list = List::new(items)
.block(Block::default().borders(Borders::ALL).title("List"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol("> ");
frame.render_widget(list, chunks[1]);
// フッター
let footer = Paragraph::new("Press 'q' to quit")
.block(Block::default().borders(Borders::ALL))
.style(Style::default().fg(Color::Gray));
frame.render_widget(footer, chunks[2]);
}
ステートフルなウィジェット
use ratatui::{
widgets::{StatefulWidget, TableState},
Frame,
};
struct App {
table_state: TableState,
items: Vec<Vec<String>>,
}
impl App {
fn new() -> Self {
Self {
table_state: TableState::default(),
items: vec![
vec!["Row 1".to_string(), "Data 1".to_string()],
vec!["Row 2".to_string(), "Data 2".to_string()],
vec!["Row 3".to_string(), "Data 3".to_string()],
],
}
}
fn next(&mut self) {
let i = match self.table_state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.table_state.select(Some(i));
}
fn previous(&mut self) {
let i = match self.table_state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.table_state.select(Some(i));
}
}
高度な機能
カスタムウィジェット
use ratatui::{
buffer::Buffer,
layout::Rect,
style::{Color, Style},
widgets::Widget,
};
struct MyWidget {
text: String,
style: Style,
}
impl Widget for MyWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
buf.set_string(area.x, area.y, &self.text, self.style);
}
}
// 使用例
let widget = MyWidget {
text: "Custom Widget".to_string(),
style: Style::default().fg(Color::Magenta),
};
frame.render_widget(widget, area);
グラフとチャート
use ratatui::{
symbols,
widgets::{Axis, Chart, Dataset, GraphType},
};
let datasets = vec![
Dataset::default()
.name("data1")
.marker(symbols::Marker::Dot)
.graph_type(GraphType::Line)
.style(Style::default().fg(Color::Cyan))
.data(&[(0.0, 5.0), (1.0, 6.0), (2.0, 7.0)]),
];
let chart = Chart::new(datasets)
.block(Block::default().title("Chart").borders(Borders::ALL))
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.bounds([0.0, 10.0])
.labels(["0", "5", "10"]),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.bounds([0.0, 10.0])
.labels(["0", "5", "10"]),
);
frame.render_widget(chart, area);
エコシステム
関連パッケージ
- ratatui-macros: 便利なマクロ集
- tui-textarea: テキストエリアウィジェット
- tui-input: 入力フィールドウィジェット
- tui-tree-widget: ツリービューウィジェット
- tui-scrollview: スクロール可能なビュー
- tui-logger: ログ表示ウィジェット
テンプレート
- ratatui-templates: 公式テンプレート集
- cargo-generate: プロジェクト生成ツール
実例プロジェクト
- gitui: Git TUIクライアント
- bottom: システムモニター
- bandwhich: ネットワークモニター
- diskonaut: ディスク使用状況ビューア
利点
- モダンな設計: 最新のRustのベストプラクティスに従う
- 活発な開発: 継続的な改善と新機能追加
- 豊富な機能: 多様なウィジェットとレイアウトオプション
- 優れた性能: 効率的なレンダリングアルゴリズム
- クロスプラットフォーム: 主要なOSとターミナルエミュレータに対応
制約事項
- 学習曲線: Rustの知識が必要
- イミディエートモード: 複雑な状態管理は開発者の責任
- ターミナル制限: ターミナルの機能に依存
- マウスサポート: バックエンドに依存
他のライブラリとの比較
項目 | Ratatui | Cursive | tui-realm |
---|---|---|---|
レンダリング | イミディエート | リテインド | コンポーネント |
学習コスト | 中 | 低〜中 | 中〜高 |
パフォーマンス | 高 | 高 | 中 |
柔軟性 | 非常に高 | 中 | 高 |
ウィジェット | 豊富 | 豊富 | 拡張可能 |
まとめ
Ratatuiは、Rustで本格的なTUIアプリケーションを構築するための最も人気のある選択肢です。活発なコミュニティ、豊富な機能、優れたパフォーマンスを提供し、シンプルなCLIツールから複雑なダッシュボードまで幅広いアプリケーションの開発に適しています。特に、柔軟性と制御を重視する開発者にとって理想的な選択です。