Expand description
ratatui is a library that is all about cooking up terminal user interfaces (TUIs).
Get started
Adding ratatui as a dependency
Add the following to your Cargo.toml:
[dependencies]
crossterm = "0.27"
ratatui = "0.23"
The crate is using the crossterm backend by default that works on most platforms. But if for
example you want to use the termion backend instead. This can be done by changing your
dependencies specification to the following:
[dependencies]
termion = "2.0.1"
ratatui = { version = "0.23", default-features = false, features = ['termion'] }
The same logic applies for all other available backends.
Creating a Terminal
Every application using ratatui should start by instantiating a Terminal. It is a light
abstraction over available backends that provides basic functionalities such as clearing the
screen, hiding the cursor, etc.
use std::io;
use ratatui::prelude::*;
fn main() -> Result<(), io::Error> {
let stdout = io::stdout();
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
Ok(())
}If you had previously chosen termion as a backend, the terminal can be created in a similar
way:
use std::io;
use ratatui::prelude::*;
use termion::raw::IntoRawMode;
fn main() -> Result<(), io::Error> {
let stdout = io::stdout().into_raw_mode()?;
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
Ok(())
}You may also refer to the examples to find out how to create a Terminal for each available
backend.
Building a User Interface (UI)
Every component of your interface will be implementing the Widget trait. The library comes
with a predefined set of widgets that should meet most of your use cases. You are also free to
implement your own.
Each widget follows a builder pattern API providing a default configuration along with methods
to customize them. The widget is then rendered using Frame::render_widget which takes your
widget instance and an area to draw to.
The following example renders a block of the size of the terminal:
use std::{io, thread, time::Duration};
use ratatui::{prelude::*, widgets::*};
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
fn main() -> Result<(), io::Error> {
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.draw(|f| {
let size = f.size();
let block = Block::default()
.title("Block")
.borders(Borders::ALL);
f.render_widget(block, size);
})?;
// Start a thread to discard any input events. Without handling events, the
// stdin buffer will fill up, and be read into the shell when the program exits.
thread::spawn(|| loop {
event::read();
});
thread::sleep(Duration::from_millis(5000));
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
Ok(())
}Layout
The library comes with a basic yet useful layout management object called Layout. As you may
see below and in the examples, the library makes heavy use of the builder pattern to provide
full customization. And Layout is no exception:
use ratatui::{prelude::*, widgets::*};
fn ui<B: Backend>(f: &mut Frame<B>) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints(
[
Constraint::Percentage(10),
Constraint::Percentage(80),
Constraint::Percentage(10)
].as_ref()
)
.split(f.size());
let block = Block::default()
.title("Block")
.borders(Borders::ALL);
f.render_widget(block, chunks[0]);
let block = Block::default()
.title("Block 2")
.borders(Borders::ALL);
f.render_widget(block, chunks[1]);
}This let you describe responsive terminal UI by nesting layouts. You should note that by default the computed layout tries to fill the available space completely. So if for any reason you might need a blank space somewhere, try to pass an additional constraint and don’t use the corresponding area.
Features
The crate provides a set of optional features that can be enabled in your cargo.toml file.
Generally an application will only use one backend, so you should only enable one of the following features:
-
crossterm(enabled by default) — enables theCrosstermBackendbackend and adds a dependency on the Crossterm crate. -
termion— enables theTermionBackendbackend and adds a dependency on the Termion crate. -
termwiz— enables theTermwizBackendbackend and adds a dependency on the Termwiz crate.
The following optional features are available for all backends:
-
serde— enables serialization and deserialization of style and color types using the Serde crate. This is useful if you want to save themes to a file. -
macros— enables theborder!macro. -
all-widgets— enables all widgets.
Widgets that add dependencies are gated behind feature flags to prevent unused transitive dependencies. The available features are:
widget-calendar— enables thecalendarwidget module and adds a dependency on the Time crate.
Modules
- This module provides the backend implementations for different terminal libraries.
- A prelude for conveniently writing applications using this library.
stylecontains the primitives used to control how your user interface will look.- Primitives for styled text.
Macros
- Assert that two buffers are equal by comparing their areas and content.
- border
macrosMacro that constructs and returns aBordersobject from TOP, BOTTOM, LEFT, RIGHT, NONE, and ALL. Internally it creates an emptyBordersobject and then inserts each bit flag specified into it usingBorders::insert().
Structs
CompletedFramerepresents the state of the terminal after all changes performed in the lastTerminal::drawcall have been applied. Therefore, it is only valid until the next call toTerminal::draw.- A consistent view into the terminal state for rendering a single frame.
- An interface that Ratatui to interact and draw
Frames on the user’s terminal. - Options to pass to
Terminal::with_options
Enums
- Represents the viewport of the terminal. The viewport is the area of the terminal that is currently visible to the user. It can be either fullscreen, inline or fixed.