Eleven apps, rebuilt¶
intuiTUIve is tested against real programs. We take a well-known terminal app, most of them ratatui apps, and rebuild it on intuiTUIve from the framework's components only. This page shows the eleven rebuilds: what each one clones, a recording of it, how to run it, the components it is built from, its size, and the report written while building it.
Each clone is an example in
crates/rich-intuituive/examples/,
with a test file of its own in
tests/
that drives it headless. None reuses the original's code: the layout, keys
and strings are rebuilt, and each example's header credits the original
and its licence. To port an app of your own, read
Porting a ratatui app.
The demo loop¶
The clones are a loop, and each turn of it is a round:
- Clone a real app from intuiTUIve's components only. Nothing in the framework changes during the round, and the example draws no widget of its own to stand in for a missing one.
- Write down the gaps. What the clone needs and cannot get goes in its report: missing components, bugs, friction with the existing APIs, and the components that would make it shorter or more faithful.
- Add them. Gaps chosen from the reports are built into the framework.
- Rebuild each clone on what was added, and report again.
The loop goes on until a clone uses intuiTUIve's components only; then we pick more apps.
One rule holds throughout: core components are generic. A core
component must be reusable by other components, with no domain types,
names or parameters (no paths, files, samples or one app's shapes).
Anything only one domain could use is a plugin, an off-by-default feature
such as files, pcm, wav or art, built on a generic core piece where
there is one. The Yazi clone's Miller columns are the files plugin's
files::miller, over the core's miller_of. The rule, and every round's
gaps, are in
what the demos are missing.
| Clone | Original | Example | Lines | Tests | Report |
|---|---|---|---|---|---|
| files | Yazi | files.rs |
1,198 | 47 | rounds 1–4 |
| scope | scope-tui | scope.rs |
1,274 | 31 | rounds 1–4 |
| git | gitui | git.rs |
2,204 | 23 | git |
| top | bottom | top.rs |
2,415 | 25 | top |
| http | Slumber | http.rs |
2,026 | 22 | http |
| blocks | rata-tetris | blocks.rs |
959 | 18 | blocks |
| csv | csvlens | csv.rs |
1,375 | 14 | csv |
| disk | diskonaut | disk.rs |
1,192 | 21 | disk |
| music | termusic | music.rs |
1,512 | 20 | music |
| tasks | taskwarrior-tui | tasks.rs |
2,412 | 27 | tasks |
| raycast | (an original game) | raycast/ |
2,891 | 28 | raycast |
Lines are the example's own, comments included. Every recording on this
page is a tape in docs/tapes/, run
against the example by rich record; CI replays each one and compares its
screenshots' text with the committed ones.
files: Yazi¶
A file manager in the style of Yazi:
the parent, current and preview columns, Yazi's keymap and status line,
tabs, a selection, yank and paste, a filter, search, bulk rename, the
finder (z), frecency (Z), and a task manager for file jobs.

Which-key after , |
An image preview | The task manager |
|---|---|---|
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --features files --example files -- DIR
cargo run -p rs-rich-intuituive --features files,archive,watch,art --example files
It needs files; archive adds archive previews, watch follows the
disk, and art draws images.
Built from: the files plugin's miller (on the core's miller_of),
tabs (on tab_set and history), selection (on multi_select),
Yank, finder_with (on finder_of), frecency, spot (on facts),
bulk_rename, shell and search, and its tasks (on the core's jobs);
the core's cursor_by, list_search, seg_gauge, fuzzy_list,
tabs(..).fit() and help_with. The porting guide walks through it:
a Yazi-style file manager.
scope: scope-tui¶
An audio scope in the style of scope-tui: an oscilloscope, a vectorscope and a spectroscope over a test signal, raw PCM from a file or a pipe, or a sound card.

| Oscilloscope | Vectorscope | Spectroscope |
|---|---|---|
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example scope --features pcm # a test signal
cargo run -p rs-rich-intuituive --example scope --features pcm -- file PATH # raw PCM
cargo run -p rs-rich-intuituive --example scope --features audio -- audio # a sound card
Built from: rs-rich-ext's Chart (Braille lines, a layer a grid
line); the pcm plugin's Capture (a simulated one for the test
signal), latest_with_state and audio::play; the core's modes (each
scope's keys bound and listed only while it shows), bind_toggle,
bind_step, bind_scaled, recent and the Proxy that wakes the loop
from another thread. The porting guide walks through it:
scope-tui, an oscilloscope.
git: gitui¶
A git client in the style of gitui:
its tabs, the unstaged and staged trees beside the diff, staging by file,
hunk and line, the commit popup, the log with branch and tag markers, a
commit's details, branches and stashes. It runs the git on the PATH.

| Status | Staged | Log | Details |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Built from: tree_keyed with status prefixes (TreeItem::prefix),
list_rows(..).range(..) for the diff's line selection, shown_when and
size_with for gitui's focus-driven layout, on_focus, key_hints_with
for gitui's key bar, and keyed for the Files tab's viewer.
top: bottom¶
A system monitor in the style of
bottom (btm): CPU, memory and
network graphs, temperatures, disks, and a process table to sort, search,
group, show as a tree and kill from. It reads Linux's /proc and /sys.

The stills are of the help, since the dashboard is this machine's live data:
| The help | Its process keys |
|---|---|
![]() |
![]() |
cargo run -p rs-rich-intuituive --example top
cargo run -p rs-rich-intuituive --example top -- --basic
Built from: each widget a focus_scope moved between by
bind_directional_focus (on focus::neighbour), shown_when for the
expanded widget, table_with with columns_with and Column::priority,
a query::Grammar of bottom's search keywords, title_with for the
load averages, and rs-rich-ext's Chart for the graphs.
http: Slumber¶
A terminal HTTP client in the style of Slumber: a YAML collection of profiles and recipes, templates, the request's query, headers and body, and the response, filtered by JSONPath or a shell command. Requests go over plain HTTP/1.1 (no TLS).

| Query | Response | Filtered | Profiles |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example http \
--features rich-ext/yaml,rich-ext/jsonpath,watch -- slumber.yml
It needs rs-rich-ext's yaml and jsonpath; with watch the collection
is read again when it changes.
Built from: one tree laid out by shown_when, hidden_when and
size_with; focus_within to focus a pane a switch has not built yet;
focus_border for Slumber's double border; titles from state
(panel_with, add_title_with); tree_keyed and tree_reveal for the
recipes; a Timer paused while no request runs; input history.
blocks: rata-tetris¶
The falling-block game rata-tetris, NES-style: the seven pieces from a shuffled bag, gravity in NES frames, levels, a ghost piece, statistics and a top score, plus a hold panel.

| Title | Playing | Game over |
|---|---|---|
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example blocks
cargo run -p rs-rich-intuituive --example blocks -- --seed 7
Built from: a fixed_step of one NES frame with catch-up
(Timer::max_catch_up), paused off the playing screen; Node::repeat for
the NES's DAS and ARR; App::min_size; a composited layers backdrop;
state_file and write_atomic for the top score; and the falling piece
and its ghost as sprites on a stage (sprite::stage_with).
csv: csvlens¶
A CSV viewer in the style of csvlens: a table over a CSV or TSV file (or stdin), read lazily, with csvlens's keys to find, filter, sort, select cells, columns or rows, freeze columns and wrap long cells.

| Table | Find | Filter | Help |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example csv -- FILE.csv
some-command | cargo run -p rs-rich-intuituive --example csv
Built from: the file as a TableSource, with view_of to keep, find
and sort its rows on a background task; one reactive table with
columns_with, freeze_columns_with, multiline_when and
Column::max_percent; TableLayout; a command_line with a shared
history for the prompts; and core's Text::markup().
disk: diskonaut¶
A disk-space treemap in the style of diskonaut: the folder's children as tiles sized by the space they take, drawn while the scan runs, then browsed, zoomed and pruned. Deleting is real.

| Map | Selected | Inside a folder | Delete? |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example disk -- DIR
cargo run -p rs-rich-intuituive --example disk -- DIR --apparent-size
Built from: layout::squarify for the tiles, focus::neighbour to
move between them, fit_text and truncate_middle for every line that
picks the longest form that fits, keyed for the map, App::min_size,
and a grid with collapse_borders to join the tiles' lines.
music: termusic¶
A music player in the style of
termusic: the library tree, the
playlist, the progress gauge, lyrics from a .lrc file, the album cover
and the key footer. There is no sound: playback is a play head on the
app's clock, and WAV is the one format it reads.

| Library | Playing | Help |
|---|---|---|
![]() |
![]() |
![]() |
It needs wav (WAV files through hound) and art (the cover).
Built from: a transport play head (play, seek, speed, the track's
end); panel_with titles from state; tree_keyed and tree_reveal for
the library; TableOptions::symbol_for for the playlist's markers;
keyed and shown_when for the cover; HelpOptions::all_panes.
tasks: taskwarrior-tui¶
A Taskwarrior front end in the style of
taskwarrior-tui: the report
sorted by urgency over the selected task's details, Taskwarrior's filter
syntax, the command bar for new tasks and changes, marks, undo, contexts,
the Projects view and a calendar. The tasks are kept as JSON lines in a
directory, as task export writes them.

| Report | Filter | Completion | Projects |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
DIR defaults to $TMPDIR/intuituive-tasks, filled with a few tasks the
first time.
Built from: a query::Grammar of Taskwarrior's filter syntax over a
Record; dates::parse_with and rs-rich-interact's Zone;
command_line_with with completion (Mode::complete) and a history per
action; one reactive table with columns_with, cursor_by and
symbol_for; year_view_with for the calendar.
raycast¶
Not a clone but an original: a first-person ray caster in the style of the early-90s shooters, with doors, guards, pickups and two levels, drawn in half blocks, quadrants, Braille, or real pixels through Kitty's or iTerm2's protocol. Its levels, textures, sprites and face are made in code.
| Title | Start | Map |
|---|---|---|
![]() |
![]() |
![]() |
cargo run -p rs-rich-intuituive --example raycast --features art --release
cargo run -p rs-rich-intuituive --example raycast --features art --release -- --mode braille
Built from: a fixed_step of a tic (35 a second) with catch-up;
on_key_up, Ctx::releases_reported and App::all_keys for held keys;
pixels_fit and pixels for the view and the face (DrawCx::rect to
place the image); keyed with on_unmount to swap cells for pixels.
What the rounds added¶
Rounds 1 to 4 rebuilt the Yazi and scope-tui clones four times. Each time
their reports led to new pieces: keys and pop-ups, list and table rows,
the files plugin, the pcm, audio and viz plugins, and runtime
fixes. Round 5 cloned the nine apps above it and gathered the gaps they
shared; round 6 built them (tables, trees and lists that follow state,
layout and focus from state, keyed nodes, a command line with completion,
queries and dates, fixed steps and held keys, sprites); and round 7
rebuilt the nine on round 6. The table of what replaced what, the bugs
found, and the gaps still open are in
what the demos are missing.
Real Doom¶
rs-rich-doom runs
Doom itself (doomgeneric) in the terminal, rendered through intuiTUIve: the
engine runs on a latest thread, and its 320x200 frames are drawn in half
blocks, Braille, or Kitty, Sixel or iTerm2 pixels, at 33 to 35 frames a
second, with sound effects through cpal. It is a separate repository,
under the GPL (the engine is GPL), and it depends on this one. What it
needed from rs-rich is listed in
Real Doom (rs-rich-doom).




































