Ratatui and Text‑based User Interfaces #
I have been trying Ratatui TUI, a Rust crate for building Text-based User Interface (TUI) apps, which typically run in the Terminal. Ratatui, along with Go-based Bubble Tea might be responsible for the recent growth in TUIs. Some examples of TUI apps are Lazygit, glow, Soft Serve, ATAC and rlt. C++ programmers are not left out — FTXUI is a modern C++ library for building TUIs.
You use the Ratatui crate to build command line apps in Rust, though it is a little different to other Rust libraries like clap and inquire. clap focusses on managing and parsing command line flags (its name is an acronym: Command Line Argument Parser). inquire, is designed for interacting with the user, prompting them for information via the command line. Ratatui is different to both, and gives you more control over the text-based app’s user interface layout and handling interaction.
🧑🏽🎓 Ratatui Learning Resources #
Ratatui is a powerful library, so there is a little to learn, and the project provides three beginner tutorials to help flatten the learning curve. These are:
- Ratatui Hello World Tutorial , which is a good starting point if you are quite new to the Rust ecosystem;
- Counter App , which takes things up a level and introduces immediate mode rendering; and
- JSON Editor , which introduces more sophisticated layouts.
If this is your first Rust app, you might want to start with either Command line app in Rust , or probably The Rust Programming Language , both free web books.
🧱 What I Built #
After following the tutorials, a nice extension was to create a basic numbers game, inspired by the UK TV Countdown quiz . For this arithmetic challenge, the player randomly picks six numbers, then using +, -, * and / operators, tries to arrive at a target.
This little game provided a natural extension to the JSON editor tutorial, mentioned above.
⚙️ Project setup #
Beyond the ratatui
and crossbeam
crates
used in the JSON tutorial, I added num_parser
and rand
. Naturally, rand
was useful for generating the target and helping
select the six, initial numbers.
I set the game up, so the player typed in their solution attempt, with their chosen numbers, using
familiar algebraic notation. For example, let’s say the target is 326
and the six numbers are 1
, 2
, 2
, 75
, 50
and 25
. Here, it is possible to reach the target exactly, and the player could enter their solution
into the Ratatui app as:
The num_parser
crate can parse that expression and yield the result
(326
), significantly reducing the number of lines of code I had to
write.
That was all I needed for dependencies: crossterm
, num_parser
, rand
and ratatui
.
🧑🏽🍳 What I Liked about Ratatui #
📚 Fantastic Docs #
The three tutorials are very well written, and provide a great introduction to using Ratatui, including unit testing your app. Beyond the tutorials, I found the official Ratatui API docs were detailed enough to solve all the queries I had as I built the app.
📦 Leveraging crates.io #
Being able to leverage the Rust crate ecosystem was a huge help. I mentioned num_parser
did a lot of heavy-lifting. This was quick to find num_parser
using crates.io . Although a similar C++ library might exist, I don’t think I could have found it so
easily. I am not familiar enough with the Go ecosystem to comment on how that would have worked
out for me, drop a comment below if you are familiar, or if you are a C++ aficionado, and know an
easy way to find C++ libraries.
🖥️ Trying Ratatui TUI: Immediate Mode #
I kept the app structure from the JSON tutorial, that is, with three main source files:
-
src/main.rs
: contains the main loop, draws the UI and listens for UI events, immediately calling app methods; -
src/app.rs
: manages app state and provides helper functions the app calls on user event; and -
src/ui.rs
: generates the UI based on the current app state.
The immediate mode pattern worked well, writing how the app UI should look for any given state, with Rust pattern matching helping me get going quicker, making sure I covered all possible states, with no surprises.
As an example of how this worked, we might look at the initial number picking. The player presses [ to pick a small number and ] for a large one. These key presses are captured in event
listener code in src/main.rs
:
So pressing those square bracket keys triggers an app state update (src/app.rs
):
Then the UI model is updated (src/ui.rs
):
Hence, the current app state gets reflected on the next enumeration of the event loop.
There is a link further down to the complete code for the project.
🏁 Trying Ratatui TUI: What Next? #
So far, I have a minimal proof of concept. I would like to remove some rough edges. In particular:
- add some fireworks to make the victory screen feel a little more of a celebration;
- add sound feedback when the user hits keys; and
- improve gameplay.
For improving gameplay, there are already different messages depending on how close to the target you got. However, I would like to take this to the next level, adding a game timer and putting best times on a high-score board. This definitely provides motivation for me playing Sudoku Pi (also written in Rust) , and I hope it will translate to this game.
🗳 Poll #
🙌🏽 Trying Ratatui TUI: Wrapping Up #
In this post on trying Ratatui TUI, we looked got an introduction to immediate mode user interfaces in Rust. In particular, we saw:
- TUI alternatives to Rust’s Ratatui in Go and C++;
- other Rust Terminal app tooling and how Ratatui is different; and
- some learning resources for getting started with Ratatui.
I hope you found this useful. As promised, you can get the full project code on the Rodney Lab GitHub repo . I would love to hear from you, if you are also new to Rust game development. Do you have alternative resources you found useful? How will you use this code in your own projects?
🙏🏽 Trying Ratatui TUI: Feedback #
If you have found this post useful, see links below for further related content on this site. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on X, giving me a mention, so I can see what you did. Finally, be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please consider supporting me through Buy me a Coffee.
Just dropped a new post on trying out Ratatui, building a text-based UI game.
— Rodney (@askRodney) June 5, 2024
I run through alternatives, the Rust Terminal crate ecosystem and what I liked about Ratatui.
Hope you find it useful!
https://t.co/BfyxbcA12k #askRodney
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on X (previously Twitter) and also, join the #rodney Element Matrix room. Also, see further ways to get in touch with Rodney Lab. I post regularly on Game Dev as well as Rust and C++ (among other topics). Also, subscribe to the newsletter to keep up-to-date with our latest projects.