Ratatui knowledge patch
Reference index
| Reference |
Topics |
| migration-and-configuration.md |
MSRV, crate split, Cargo features, no_std, breaking migrations, Serde, prelude |
| layout-text-and-style.md |
typed layout, flex, overlap, rectangles, text, styles, colors, borders |
| widgets-and-selection.md |
tables, lists, tabs, scrollbars, sparklines, titles, calendars, reference widgets |
| charts-canvas-and-symbols.md |
grouped bars, line gauges, canvas markers, clipping, layering, runtime symbols |
| terminal-backends-and-events.md |
lifecycle, viewports, drawing, cursors, backend traits, event scheduling |
| architecture-state-and-testing.md |
components, TEA, stateful rendering, templates, snapshots, safe buffers |
Breaking changes and deprecations
Toolchain and crates
- Ratatui 0.30.0 requires Rust 1.86.0 and Rust 2024. The current 0.31.0
workspace requires Rust 1.88.0.
- Applications may keep using
ratatui. Libraries can use ratatui-core,
ratatui-widgets, and backend-specific crates for narrower dependencies.
- A
no_std build disables defaults. Add layout-cache when a std build
disables defaults but still needs cached layout, and add portable-atomic
only on targets without native atomics.
palette and serde require std.
Imports and renamed APIs
// 0.30.0+
use ratatui::layout::HorizontalAlignment;
use ratatui::widgets::{BlockExt, TitlePosition};
- Layout
Alignment is now HorizontalAlignment.
widgets::block and widgets::block::Title were removed. Pass content
convertible to Line into Block::title; use title_top/title_bottom.
- The prelude includes
Position and Size, but not Styled, Marker,
CompletedFrame, TerminalOptions, or Viewport.
Style migration
const PANEL: Style = Style::new().blue().on_black();
let reset = Style::reset();
- Stylize methods are inherent on
Style; Style itself no longer
implements Styled.
- Replace
style.reset() with the associated function Style::reset().
- Styling an owned
String consumes it and produces Span<'static>; clone it
first if it is still needed.
Backends
Custom backends must define Backend::Error and implement clear_region.
Generic terminal helpers should return Result<T, B::Error> rather than
assuming std::io::Error; TestBackend uses Infallible.
Generic backend conversions were replaced by explicit traits:
let color = Color::from_crossterm(value);
let backend_color = color.into_crossterm();
Equivalent FromTermion/IntoTermion and FromTermwiz/IntoTermwiz traits
are available. Prefer ratatui::crossterm imports so the version matches the
enabled backend feature.
Widget and buffer APIs
- Implement
Widget for &Foo instead of relying on a direct
WidgetRef for Foo implementation to gain Widget.
StatefulWidget::State and StatefulWidgetRef::State may be unsized.
Cell::symbol is Option<CompactString>; direct access must handle None.
symbols::Marker is non-exhaustive. Add a wildcard match arm.
Marker::Block is now a full block; use Marker::Bar for the former
upper-half-block canvas appearance.
Rect::area() returns u32, and its Positions fields are private.
LineGauge::line_set is deprecated; set filled_symbol and
unfilled_symbol separately.
Inference traps
Avoid unnecessary .into() when an API itself accepts Into:
let bar = Bar::default().label("name").text_value("42");
let tabs = Tabs::new(["A", "B"]).select(None);
Explicit conversions may be needed around Line: From<Cow<str>>, while
Tabs::select(selected.into()) may need an explicitly typed option or
selected as usize.
High-value layout APIs
Typed areas
let layout = Layout::vertical([Constraint::Length(3), Constraint::Min(0)]);
let [header, body] = area.layout(&layout);
Use Rect::try_layout or Layout::try_areas for fallible arrays, and
Rect::layout_vec for a vector. Center areas with Rect::centered,
centered_vertically, or centered_horizontally; expand with Rect::outer.
Fill, flex, and overlap
Constraint::Fill(weight) proportionally divides excess space.
- Conflict priority is
Min > Max > Length > Percentage > Ratio > Fill.
Flex::SpaceAround now has CSS semantics; Flex::SpaceEvenly preserves the
earlier equal-edge-gap behavior.
Layout::split_with_spacers exposes generated spacer rectangles.
- Negative spacing creates overlaps. Later rendering wins shared cells:
let panes = Layout::horizontal(constraints).spacing(-1).split(area);
High-value terminal APIs
Lifecycle
For the default Crossterm terminal, prefer managed execution:
ratatui::run(|terminal| {
terminal.draw(|frame| frame.render_widget("Hello", frame.area()))?;
Ok(())
})
For manual control, call init, preserve the application result, call
restore, and then return the result. Use try_init,
try_init_with_options, and try_restore to propagate lifecycle errors.
Viewports and fallible drawing
draw tracks backend resizing for fullscreen and inline viewports, but a
fixed viewport stays at its configured Rect.
- Explicit
Terminal::resize changes fixed viewports.
Terminal::clear uses the latest resized area.
Terminal::try_draw accepts a fallible callback; errors prevent the update.
get_cursor_position/set_cursor_position replace untyped cursor methods.
Terminal::size() returns the real backend Size, not a viewport Rect.
High-value widget APIs
Tables
state.select_column(Some(column));
state.select_cell(Some((row, column)));
Use column_highlight_style and cell_highlight_style. Overlapping selection
styles apply as row, then column, then cell. Table can be collected from
rows, and Table::flex controls unused column width.
Scrollbars, lists, and tabs
- Initialize a scrollbar with
ScrollbarState::new(total) or it renders
blank; then set position and optionally viewport_content_length.
- Set scrollbar orientation before custom symbols, because
orientation
resets the symbol set.
- List selection beyond the item count clamps to the last item.
Tabs::select(None) renders no selected tab. The default selected style is
reversed.
Optional and stateful rendering
Option<W>: Widget, so None draws nothing:
frame.render_widget(show.then(|| Paragraph::new("Details")), area);
Stateful widgets mutate separate persistent state during full-frame redraws.
Keep child widget state inside the parent state and pass mutable model access
when rendering can adjust offsets. For lightweight in-place mutation,
implement Widget for &mut MyWidget.
Charts and canvas
BarChart::grouped builds multiple labeled bar groups, and Bar implements
Styled.
- Canvas adds
Quadrant (2×2), Sextant (2×3), and Octant (2×4) markers.
- Canvas coordinates round to the nearest grid cell; out-of-bounds line starts
are clipped, and
Painter::bounds() exposes the current bounds.
- Overlaid charts and text preserve Braille and block marks for composition.
- Canvas grids may exceed 65,535 pseudo-pixels.
Text and color reminders
Text += other appends lines but ignores the appended text's top-level
style and alignment; line/span attributes remain.
Text, Line, and Span implement UnicodeWidthStr with width and
width_cjk; Span suppresses Unicode control characters.
- Styles patch in widget → text → line → span order.
Color::from_hsl takes one palette::Hsl with saturation/lightness in
0.0..=1.0; Color::from_hsluv is also available with palette.
ratatui::style::palette::tailwind supplies compile-time color families.
Testing reminders
- Snapshot a fixed-size
TestBackend with insta and review changes with
cargo insta review.
- Clip a custom widget's area with
area.intersection(buf.area) before direct
buffer writes.
- Expect snapshot changes from concise text/style
Debug, nearest-cell canvas
rounding, padded line-gauge labels, and inherited-alignment truncation.
1---2name: ratatui-knowledge-patch3description: Ratatui4license: MIT5---678# Ratatui knowledge patch910## Reference index1112| Reference | Topics |13|---|---|14| [migration-and-configuration.md](references/migration-and-configuration.md) | MSRV, crate split, Cargo features, `no_std`, breaking migrations, Serde, prelude |15| [layout-text-and-style.md](references/layout-text-and-style.md) | typed layout, flex, overlap, rectangles, text, styles, colors, borders |16| [widgets-and-selection.md](references/widgets-and-selection.md) | tables, lists, tabs, scrollbars, sparklines, titles, calendars, reference widgets |17| [charts-canvas-and-symbols.md](references/charts-canvas-and-symbols.md) | grouped bars, line gauges, canvas markers, clipping, layering, runtime symbols |18| [terminal-backends-and-events.md](references/terminal-backends-and-events.md) | lifecycle, viewports, drawing, cursors, backend traits, event scheduling |19| [architecture-state-and-testing.md](references/architecture-state-and-testing.md) | components, TEA, stateful rendering, templates, snapshots, safe buffers |2021## Breaking changes and deprecations2223### Toolchain and crates2425- Ratatui 0.30.0 requires Rust 1.86.0 and Rust 2024. The current 0.31.026 workspace requires Rust 1.88.0.27- Applications may keep using `ratatui`. Libraries can use `ratatui-core`,28 `ratatui-widgets`, and backend-specific crates for narrower dependencies.29- A `no_std` build disables defaults. Add `layout-cache` when a `std` build30 disables defaults but still needs cached layout, and add `portable-atomic`31 only on targets without native atomics.32- `palette` and `serde` require `std`.3334### Imports and renamed APIs3536```rust37// 0.30.0+38use ratatui::layout::HorizontalAlignment;39use ratatui::widgets::{BlockExt, TitlePosition};40```4142- Layout `Alignment` is now `HorizontalAlignment`.43- `widgets::block` and `widgets::block::Title` were removed. Pass content44 convertible to `Line` into `Block::title`; use `title_top`/`title_bottom`.45- The prelude includes `Position` and `Size`, but not `Styled`, `Marker`,46 `CompletedFrame`, `TerminalOptions`, or `Viewport`.4748### Style migration4950```rust51const PANEL: Style = Style::new().blue().on_black();52let reset = Style::reset();53```5455- Stylize methods are inherent on `Style`; `Style` itself no longer56 implements `Styled`.57- Replace `style.reset()` with the associated function `Style::reset()`.58- Styling an owned `String` consumes it and produces `Span<'static>`; clone it59 first if it is still needed.6061### Backends6263Custom backends must define `Backend::Error` and implement `clear_region`.64Generic terminal helpers should return `Result<T, B::Error>` rather than65assuming `std::io::Error`; `TestBackend` uses `Infallible`.6667Generic backend conversions were replaced by explicit traits:6869```rust70let color = Color::from_crossterm(value);71let backend_color = color.into_crossterm();72```7374Equivalent `FromTermion`/`IntoTermion` and `FromTermwiz`/`IntoTermwiz` traits75are available. Prefer `ratatui::crossterm` imports so the version matches the76enabled backend feature.7778### Widget and buffer APIs7980- Implement `Widget for &Foo` instead of relying on a direct81 `WidgetRef for Foo` implementation to gain `Widget`.82- `StatefulWidget::State` and `StatefulWidgetRef::State` may be unsized.83- `Cell::symbol` is `Option<CompactString>`; direct access must handle `None`.84- `symbols::Marker` is non-exhaustive. Add a wildcard match arm.85- `Marker::Block` is now a full block; use `Marker::Bar` for the former86 upper-half-block canvas appearance.87- `Rect::area()` returns `u32`, and its `Positions` fields are private.88- `LineGauge::line_set` is deprecated; set `filled_symbol` and89 `unfilled_symbol` separately.9091### Inference traps9293Avoid unnecessary `.into()` when an API itself accepts `Into`:9495```rust96let bar = Bar::default().label("name").text_value("42");97let tabs = Tabs::new(["A", "B"]).select(None);98```99100Explicit conversions may be needed around `Line: From<Cow<str>>`, while101`Tabs::select(selected.into())` may need an explicitly typed option or102`selected as usize`.103104## High-value layout APIs105106### Typed areas107108```rust109let layout = Layout::vertical([Constraint::Length(3), Constraint::Min(0)]);110let [header, body] = area.layout(&layout);111```112113Use `Rect::try_layout` or `Layout::try_areas` for fallible arrays, and114`Rect::layout_vec` for a vector. Center areas with `Rect::centered`,115`centered_vertically`, or `centered_horizontally`; expand with `Rect::outer`.116117### Fill, flex, and overlap118119- `Constraint::Fill(weight)` proportionally divides excess space.120- Conflict priority is `Min > Max > Length > Percentage > Ratio > Fill`.121- `Flex::SpaceAround` now has CSS semantics; `Flex::SpaceEvenly` preserves the122 earlier equal-edge-gap behavior.123- `Layout::split_with_spacers` exposes generated spacer rectangles.124- Negative spacing creates overlaps. Later rendering wins shared cells:125126```rust127let panes = Layout::horizontal(constraints).spacing(-1).split(area);128```129130## High-value terminal APIs131132### Lifecycle133134For the default Crossterm terminal, prefer managed execution:135136```rust137ratatui::run(|terminal| {138 terminal.draw(|frame| frame.render_widget("Hello", frame.area()))?;139 Ok(())140})141```142143For manual control, call `init`, preserve the application result, call144`restore`, and then return the result. Use `try_init`,145`try_init_with_options`, and `try_restore` to propagate lifecycle errors.146147### Viewports and fallible drawing148149- `draw` tracks backend resizing for fullscreen and inline viewports, but a150 fixed viewport stays at its configured `Rect`.151- Explicit `Terminal::resize` changes fixed viewports.152- `Terminal::clear` uses the latest resized area.153- `Terminal::try_draw` accepts a fallible callback; errors prevent the update.154- `get_cursor_position`/`set_cursor_position` replace untyped cursor methods.155- `Terminal::size()` returns the real backend `Size`, not a viewport `Rect`.156157## High-value widget APIs158159### Tables160161```rust162state.select_column(Some(column));163state.select_cell(Some((row, column)));164```165166Use `column_highlight_style` and `cell_highlight_style`. Overlapping selection167styles apply as row, then column, then cell. `Table` can be collected from168rows, and `Table::flex` controls unused column width.169170### Scrollbars, lists, and tabs171172- Initialize a scrollbar with `ScrollbarState::new(total)` or it renders173 blank; then set `position` and optionally `viewport_content_length`.174- Set scrollbar orientation before custom symbols, because `orientation`175 resets the symbol set.176- List selection beyond the item count clamps to the last item.177- `Tabs::select(None)` renders no selected tab. The default selected style is178 reversed.179180### Optional and stateful rendering181182`Option<W>: Widget`, so `None` draws nothing:183184```rust185frame.render_widget(show.then(|| Paragraph::new("Details")), area);186```187188Stateful widgets mutate separate persistent state during full-frame redraws.189Keep child widget state inside the parent state and pass mutable model access190when rendering can adjust offsets. For lightweight in-place mutation,191implement `Widget` for `&mut MyWidget`.192193## Charts and canvas194195- `BarChart::grouped` builds multiple labeled bar groups, and `Bar` implements196 `Styled`.197- Canvas adds `Quadrant` (2×2), `Sextant` (2×3), and `Octant` (2×4) markers.198- Canvas coordinates round to the nearest grid cell; out-of-bounds line starts199 are clipped, and `Painter::bounds()` exposes the current bounds.200- Overlaid charts and text preserve Braille and block marks for composition.201- Canvas grids may exceed 65,535 pseudo-pixels.202203## Text and color reminders204205- `Text += other` appends lines but ignores the appended text's top-level206 style and alignment; line/span attributes remain.207- `Text`, `Line`, and `Span` implement `UnicodeWidthStr` with `width` and208 `width_cjk`; `Span` suppresses Unicode control characters.209- Styles patch in widget → text → line → span order.210- `Color::from_hsl` takes one `palette::Hsl` with saturation/lightness in211 `0.0..=1.0`; `Color::from_hsluv` is also available with `palette`.212- `ratatui::style::palette::tailwind` supplies compile-time color families.213214## Testing reminders215216- Snapshot a fixed-size `TestBackend` with `insta` and review changes with217 `cargo insta review`.218- Clip a custom widget's area with `area.intersection(buf.area)` before direct219 buffer writes.220- Expect snapshot changes from concise text/style `Debug`, nearest-cell canvas221 rounding, padded line-gauge labels, and inherited-alignment truncation.