Quickstart
Welcome to ratatui_ruby! This guide will help you get up and running with your first Terminal User Interface in Ruby.
Installation
See Installation in the README for setup instructions.
Tutorials
Basic Application
Here is a âHello Worldâ application that demonstrates the core lifecycle of a ratatui_ruby app.
# 1. Initialize the terminal RatatuiRuby.init_terminal begin # The Main Loop loop do # 2. Create your UI (Immediate Mode) # We define a Paragraph widget inside a Block with a title and borders. view = RatatuiRuby::Widgets::Paragraph.new( text: "Hello, Ratatui! Press 'q' to quit.", alignment: :center, block: RatatuiRuby::Widgets::Block.new( title: "My Ruby TUI App", title_alignment: :center, borders: [:all], border_style: { fg: "cyan" }, style: { fg: "white" } ) ) # 3. Draw the UI RatatuiRuby.draw do |frame| frame.render_widget(view, frame.area) end # 4. Poll for events case RatatuiRuby.poll_event in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] } break else nil end # 5. Guard against accidental output (optional but recommended) # Wrap any code that might puts/warn to prevent screen corruption. RatatuiRuby.guard_io do # SomeChattyGem.do_something end end ensure # 6. Restore the terminal to its original state RatatuiRuby.restore_terminal end
How it works
-
RatatuiRuby.init_terminal: Enters raw mode and switches to the alternate screen. -
Immediate Mode UI: On every iteration, describe your UI by creating
Dataobjects (e.g.,Paragraph,Block). -
RatatuiRuby.draw { |frame| ... }: The block receives aFrameobject as a canvas. Render widgets onto specific areas. Nothing is drawn until the block finishes, ensuring flicker-free updates. -
RatatuiRuby.poll_event: Returns a typedEventobject with predicates likekey?,mouse?,resize?, etc. ReturnsRatatuiRuby::Event::Noneif no events are pending. Use predicates to check event type without pattern matching. -
RatatuiRuby.guard_io { }: Wraps code that might write to stdout/stderr (e.g., chatty gems). Output is swallowed to prevent screen corruption. Optional but recommended for production apps. -
RatatuiRuby.restore_terminal: Essential for leaving raw mode and returning to the shell. Always wrap your loop inbegin...ensureto guarantee this runs.
Simplified API
You can simplify your code by using RatatuiRuby.run. This method handles the terminal lifecycle for you, yielding a TUI object with factory methods for widgets.
# 1. Initialize the terminal, start the run loop, and ensure the terminal is restored. RatatuiRuby.run do |tui| loop do # 2. Create your UI with methods instead of classes. view = tui.paragraph( text: "Hello, Ratatui! Press 'q' to quit.", alignment: :center, block: tui.block( title: "My Ruby TUI App", title_alignment: :center, borders: [:all], border_style: { fg: "cyan" }, style: { fg: "white" } ) ) # 3. Use RatatuiRuby methods, too. tui.draw do |frame| frame.render_widget(view, frame.area) end # 4. Poll for events with pattern matching case tui.poll_event in { type: :key, code: "q" } break else # Ignore other events end end end
How it works
-
RatatuiRuby.run: This context manager initializes the terminal before the block starts and ensuresrestore_terminalis called when the block exits (even if an error occurs). -
Widget Shorthand: The block yields a
TUIobject (here namedtui). This object provides factory methods for every widget, allowing you to writetui.paragraph(...)instead of the more verboseRatatuiRuby::Widgets::Paragraph.new(...). -
Method Shorthand: The
TUIobject also provides aliases for module functions ofRatatuiRuby, allowing you to writetui.draw(...)instead of the more verboseRatatuiRuby.draw(...). -
Pattern Matching for Events: Use
case...inwith pattern matching for elegant event dispatch. Always include anelseclause at the end to catch unmatched event types (mouse, resize, paste, focus, etc.), otherwise Ruby raisesNoMatchingPatternError.
For a deeper dive into the available application architectures (Manual vs Managed), see Application Architecture.
Adding Layouts
Real-world applications often need to split the screen into multiple areas. RatatuiRuby::Layout lets you do this easily.
loop do tui.draw do |frame| # 1. Split the screen top, bottom = tui.layout_split( frame.area, direction: :vertical, constraints: [ tui.constraint_percentage(75), tui.constraint_percentage(25), ] ) # 2. Render Top Widget frame.render_widget( tui.paragraph( text: "Hello, Ratatui!", alignment: :center, block: tui.block(title: "Content", borders: [:all], border_style: { fg: "cyan" }) ), top ) # 3. Render Bottom Widget with Styled Text # We use a Line of Spans to style specific characters text_line = tui.text_line( spans: [ tui.text_span(content: "Press '"), tui.text_span( content: "q", style: tui.style(modifiers: [:bold, :underlined]) ), tui.text_span(content: "' to quit."), ], alignment: :center ) frame.render_widget( tui.paragraph( text: text_line, block: tui.block(title: "Controls", borders: [:all]) ), bottom ) end case tui.poll_event in { type: :key, code: "q" } break else # Ignore other events end end
How it works
-
tui.layout_split(RatatuiRuby::Layout::Layout.split): Takes an area (likeframe.area) and splits it into multiple sub-areas based on constraints. -
tui.constraint_*(RatatuiRuby::Layout::Constraint): Defines how space is distributed (e.g.,percentage,length,min,max). -
Frame#render_widget(widget, rect): You pass the specific area (liketoporbottom) to render the widget into that exact region. -
tui.text_span(RatatuiRuby::Text::Span): Allows for rich styling within a single line of text.
Examples
These examples showcase the full power of ratatui_ruby. You can find their source code in the examples directory.
Widget Demos
Focused examples for individual widgets. Each demonstrates a single widget and its configuration options.
| Widget | What it demonstrates |
|---|---|
| Bar Chart | Grouped bars, data visualization, custom bar styling |
| Block | Borders, titles, padding, nested widgets |
| Box | Block + Paragraph composition, text wrapping |
| Calendar | Date highlighting, month display, event markers |
| Chart | Line/scatter plots, axes, legends, datasets |
| Gauge | Progress bars, percentage display, unicode blocks |
| Layout Split | Constraint types, flex modes, responsive layouts |
| Line Gauge | Horizontal progress, labels, thin-style gauges |
| List | Selection, scrolling, highlight styles, rich text items |
| Map | Canvas widget, world map rendering, coordinates |
| Popup | Clear widget, modal dialogs, overlay composition |
| Ratatui Logo | Decorative branding widget |
| Ratatui Mascot | ASCII art Ferris mascot |
| Rect | Geometry helpers, area calculations, contains/intersection |
| Rich Text | Spans, lines, inline styling, mixed colors |
| Scrollbar | Orientations, thumb/track styling, scroll state |
| Scroll Text | Paragraph scrolling, viewport control, long content |
| Sparkline | Mini charts, time series, bar sets |
| Style Colors | Named colors, RGB, indexed 256-color palette |
| Table | Row selection, column widths, per-cell styling |
| Tabs | Tab navigation, highlighting, dividers |
| Text Width | Unicode-aware width measurement, CJK support |
| Canvas | Drawing shapes, markers, custom graphics |
| Cell | Buffer cell inspection, styling attributes |
| Center | Centering content, horizontal/vertical alignment |
| Overlay | Layering widgets, modal backgrounds |
| Custom Render | Low-level Draw API, escape hatch for custom widgets |
Sample Applications
These larger examples combine widgets into complete applications, demonstrating real-world TUI patterns and architectures.
| Application | Architecture | What youâll learn |
|---|---|---|
| All Events | Model-View-Update | Event handling, unidirectional data flow, scalable structure |
| Color Picker | Component-Based | Hit testing, modal dialogs, encapsulated state |
| Debugging Showcase | Simple Loop | Remote debugging, Rust backtraces, improved error messages |
| Login Form | Overlay + Center | Modal forms, cursor positioning, text input |
| Stateful Interaction | State Objects | ListState/TableState, offset read-back, mouse click-to-row |
All Events
Color Picker
Debugging Showcase
Login Form
Next Steps
Now that youâve seen what ratatui_ruby can do:
-
Deep dive: Read the Application Architecture guide for scaling patterns
-
Test your TUI: See the Testing Guide for snapshot and style assertions
-
Avoid common mistakes: See Terminal Output During TUI Sessions to prevent screen corruption
-
Explore the API: Browse the full RDoc documentation
-
Learn the philosophy: Read Why RatatuiRuby? for comparisons and design decisions
-
Get help: Join the discussion mailing list





