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.
Prerequisites
Section titled “Prerequisites”Install Rust
Section titled “Install Rust”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:
rustc --versionYou should see output similar to the following (the exact version, date and commit hash will vary):
rustc 1.88.0 (6b00bc388 2025-06-23)Install Cargo generate
Section titled “Install Cargo generate”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.
cargo install --locked cargo-generateCreate a New Project
Section titled “Create a New Project”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.
cargo generate ratatui/templates hello-worldWhen prompted for a project name, enter hello-ratatui. Cargo Generate also asks for a short
description.
$ 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-ratatuiExamine the Project
Section titled “Examine the Project”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.mdThe generated Cargo.toml contains the dependencies used by the app. Ratatui draws the
interface, Crossterm talks to the terminal, and color-eyre reports errors.
[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 = 1lto = trueopt-level = "s"strip = trueThe generate command creates this default 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());}Run the App
Section titled “Run the App”Let’s build and execute the project. Run:
cd hello-ratatuicargo runYou should see the build output and then a TUI app with a hello world message.

You can press any key to exit and go back to your terminal as it was before.
Next step
Section titled “Next step”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.