Most Pomodoro timers count down and forget. Tomato Dragon writes every round to disk as it happens (which phase it was, how long it actually ran, and whether you skipped out of it early), so the history you look at afterwards is the history that happened, not a tidy reconstruction of it.
The whole thing is one immediate-mode egui tree. There is no
DOM, no template layer and no state library: the UI is a pure function of
the timer, task and stats structs, redrawn every frame.
Work and break phases with numbered sessions, and a start / pause / reset / skip control set. Sessions can also be started by hand rather than rolling on automatically.
Tasks carry state across rounds and persist between launches through
eframe’s storage layer, so closing the window does
not reset the day.
Two graph modes, This Week and Sessions, with independent Work and Breaks toggles. Rounds you skipped out of are logged and labelled as skipped rather than dropped.
Backup, restore and reset, each behind a confirmation step, plus a JSON report you can generate and save if you want to chart the numbers somewhere other than the app.
A daily tomato goal, and a policy for when that counter goes back to zero. The three policies are the whole configuration surface. The names are the ones the app ships with.
The same crate builds for the desktop and for the browser. Platform
differences are confined to two cfg-gated dependency blocks;
everything above them (timer, tasks, stats, storage) is
shared.
| egui / eframe 0.29 | Immediate-mode UI, glow renderer, accesskit enabled for platform accessibility |
| Rust 1.76+ | Edition 2021; release profile builds with LTO |
| serde · serde_json | Settings, stats and the saved report |
| chrono | Day boundaries and week bucketing for the graphs |
| Native only | notify-rust for desktop notifications, directories for the data path |
| WASM only | wasm-bindgen and web-sys, with the browser Notification API in place of notify-rust |
Version 0.1.0. The desktop and WASM targets both build and the test suite (58 tests) runs in the pre-push gate, but there are no tagged releases yet: no installer, no hosted demo, and the repository is private.
Listing platform download buttons before any build has been published would be inviting you to click nothing, so there are none here. Ask me for a build and I will send you one.
Written mostly to find out what an immediate-mode GUI feels like to maintain once it grows past a demo, and the honest answer is that the redraw-everything model stays pleasant far longer than expected, right up until you want a scroll position to survive a state change.