Skip to content

Hello Ratatui

This tutorial walks through creating a small “Hello world” TUI from Ratatui’s hello-world template. The app displays some text in the top-left corner and waits for a key before returning to the terminal. The goal here is to get an app running and look at the pieces that every Ratatui app needs.

We assume you have a basic understanding of the terminal, and have a text editor or IDE. If you don’t have a preference, VSCode with rust-analyzer makes a good default choice.

First install Rust if it is not already installed. See the Installation section of the official Rust Book for more information. Most people use rustup, a command line tool for managing Rust versions and associated tools. Ratatui 0.30.2 requires Rust 1.88 or newer. Once you have installed Rust, verify the active compiler by running:

check rust version
rustc --version

You should see output similar to the following (the exact version, date and commit hash will vary):

rustc 1.88.0 (6b00bc388 2025-06-23)

Ratatui has a few templates for starting a new project. Cargo generate creates a Rust project from one of those templates. We’ll use the hello-world template.

Install cargo-generate with the following command. The installation instructions cover other options.

Terminal window
cargo install --locked cargo-generate

Let’s create the project. In a terminal, go to the directory where you keep your projects and run the following command. The second argument selects the hello-world template. The Hello World Template README describes its other options.

create new rust project
cargo generate ratatui/templates hello-world

When prompted for a project name, enter hello-ratatui. Cargo Generate also asks for a short description.

create new rust project
$ cargo generate ratatui/templates hello-world
⚠️ Favorite `ratatui/templates` not found in config, using it as a git repository: https://github.com/ratatui/templates.git
🤷 Project Name: hello-ratatui
🔧 Destination: /path/to/projects/hello-ratatui ...
🔧 project-name: hello-ratatui ...
🔧 Generating template ...
🤷 Short description of the project: A Ratatui Hello World app
🔧 Moving generated files into: `/path/to/projects/hello-ratatui`...
🔧 Initializing a fresh Git repository
Done! New project created /path/to/projects/hello-ratatui

The command creates a new hello-ratatui directory containing a basic binary application. Its top-level files look like this:

hello-ratatui/
├── src/
│ └── main.rs
├── Cargo.toml
├── LICENSE
└── README.md

The generated Cargo.toml contains the dependencies used by the app. Ratatui draws the interface, Crossterm talks to the terminal, and color-eyre reports errors.

Cargo.toml
[package]
name = "hello-ratatui"
version = "0.1.0"
description = "A Ratatui Hello World app"
authors = ["Josh McKinney <joshka@users.noreply.github.com>"]
license = "MIT"
edition = "2024"
rust-version = "1.88"
[dependencies]
color-eyre = "0.6.5"
crossterm = "0.29.0"
ratatui = "0.30.2"
# Read the optimization guideline for more details: https://ratatui.rs/recipes/apps/release-your-app/#optimizations
[profile.release]
codegen-units = 1
lto = true
opt-level = "s"
strip = true

The generate command creates this default main.rs:

main.rs
use ratatui::{DefaultTerminal, Frame};
fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
ratatui::run(app)?;
Ok(())
}
fn app(terminal: &mut DefaultTerminal) -> std::io::Result<()> {
loop {
terminal.draw(render)?;
if crossterm::event::read()?.is_key_press() {
break Ok(());
}
}
}
fn render(frame: &mut Frame) {
frame.render_widget("hello world", frame.area());
}

Let’s build and execute the project. Run:

run the app
cd hello-ratatui
cargo run

You should see the build output and then a TUI app with a hello world message.

hello

You can press any key to exit and go back to your terminal as it was before.

That’s it. You have a working Ratatui application. The Counter App builds one without a template and adds application state, explicit key handling, and a render test.