| Crates.io | fatui |
| lib.rs | fatui |
| version | 0.1.0 |
| created_at | 2025-07-27 02:14:00.514269+00 |
| updated_at | 2025-07-27 02:14:00.514269+00 |
| description | a silly little framework for terminal user interfaces |
| homepage | https://genderphas.ing/projects/fatui |
| repository | https://genderphas.ing/projects/fatui |
| max_upload_size | |
| id | 1769660 |
| size | 1,303,530 |
fatui is an immediate-mode terminal ui library that aims to be flexible and cell-perfect.
less vaguely:
mostly, it looks like your terminal -- fatui's favorite rendering backend is just stdout. here's what it looks like captured with [asciinema]:

the cool thing about fatui is that it's
#![no_std]-friendly, meaning it can be used on the web!
the uncool thing about fatui is i haven't built that backend yet.
haven't even actually made it #![no_std] --
there's just nothing that would absolutely require it in the main code.
if you're building a full-terminal app --
something like htop or vim, which draws a ui to a terminal,
not a command-line app like grep, which is run as a command in your shell --
and you like immediate-mode guis,
then fatui is a great option.
but it's not the only option!
ratatui is a similar full-terminal immediate-mode tui crate,
but it doesn't handle any inputs -- just output.
fatui handles both input and output.
crossterm and termion are great for just raw terminal control and coloring,
but they're much lower-level.
fatui presents a much higher-level api.
if you want a docker- or kubernetes-style rich cli output just shy of a full-terminal system, let me know what you find, because i got nothin' -- even cargo just rolled their own
it's a simple, three-step process:
add fatui as a dependency to your project:
cargo add fatui
get a Backend to render to:
let mut backend = fatui::open();
// (or you can instantiate any implementation of `fatui::Backend` you like)
render the rest of the owl to it. right now that's pretty verbose and fiddly, but by the 1.0 release it'll look like:
let mut clicks = 0;
loop {
let frame = backend.step();
let (top, bottom) = frame.split(rows!(*, red "-", 1));
if top.render(Button.or_key(Key::Space)).clicked {
clicks += 1;
}
bottom.render(tfmt!(
"whoah! you've clicked {@red}{clicks}{@/} times!",
));
}
(for the current state of affairs, see the docs)
there's no layers and layers of framework you need to integrate your code into, there's no separate files with custom dsls, it's all just rust code with a loop and a handful of lightly arcane macros.
"fatui" is the plural for "silly" in italian. it could also be parsed as "make a tui", depending on how generous you are, and "fat ui" puns off "thin terminals".
fatui uses semantic versioning, but there are a couple of important things to note:
#[doc(hidden)] items, implementation details, etc.
are 100% liable to change in breaking ways in patch versions.if those are inconvenient for you, i'm sorry, but it's a hobby project. i want to enjoy my time working on it, and that means letting myself play with the latest toys.