Pomodoro focus timer with task queues, automatic work/break cycling, and screen-blocking break enforcement. Built native with Rust + Tauri.
A quick loop of Pomotoro in action — watch the full demo (1m40s).
Timer phases, task queues, ambient audio, notifications, and the break screen blocker.
| 🍅 Pomodoro engine | Configurable focus / short-break / long-break cycles with smooth visual ring and session dots. |
| ✅ Task management | Multi-session tasks with tags, search, status filters, and live progress. A starter Focus Session is auto-created on first boot. |
| 🎵 Focus audio | Ambient background sounds (rain, forest, ocean, white noise, café, fireplace, thunderstorm, brown noise) plus distinct work/break notification chimes. |
| 🔔 Smart notifications | Desktop notifications, sound alerts, phase-transition & task-completion alerts, with position and auto-dismiss control. |
| 🚫 Screen blocker | Optional full-screen overlay that forces you to actually take your break — with custom messages. |
| 🪟 System tray | Minimize to tray, start minimized, and watch the live countdown baked into the tray icon & tooltip. |
| ⌨️ Keyboard shortcuts | Cycle incomplete tasks instantly with Ctrl/Meta+Tab — no mouse needed. |
| 🎛️ Deeply configurable | Timer durations, automation, appearance, window, audio, and screen blocking — all in one settings hub. |
| ⚡ Native speed | Tauri + Rust core with SQLite persistence. Minimal resources, instant response. |
| 🖥️ Cross-platform | Windows, macOS, and Linux |
Prebuilt installers for Windows, macOS, and Linux are published with every release on the Releases page.
| Platform | Installer |
|---|---|
| Linux | *.AppImage (portable) or *.deb (Debian/Ubuntu) |
| macOS | *.dmg (universal — Intel + Apple Silicon) |
| Windows | *.msi or *.exe (NSIS) installer |
⚠️ Builds are currently unsigned. This is normal for an early project. Your OS will show a security prompt the first time you run Pomotoro:
- macOS: after dragging to Applications, run:
xattr -dr com.apple.quarantine /Applications/Pomotoro.app(or right-click → Open → Open Anyway from Finder).- Windows: click More info → Run anyway on the SmartScreen prompt.
- Linux (AppImage):
chmod +x Pomotoro_*.AppImagethen double-click.Code signing (Apple Developer ID + Windows Authenticode) is planned before 1.0.
- Rust toolchain (latest stable)
- Node.js LTS (for the React frontend)
- Build tools (installed via Cargo):
cargo install just # task runner — REQUIRED for all dev commands
cargo install tauri-cli # desktop app packager
# Optional — database migration CLI (needs SQLite dev libs, see System Dependencies)
cargo install diesel_cli --no-default-features --features sqliteLinux (recommended): run the auto-detecting installer — supports Debian/Ubuntu, Fedora/RHEL, Arch, and Alpine.
just install-deps # or: ./scripts/install-deps.shManual Linux install
# Debian / Ubuntu
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev \
libsqlite3-dev libasound2-dev libgtk-3-dev libpango1.0-dev \
libgdk-pixbuf2.0-dev libcairo2-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
# Fedora / RHEL
sudo dnf install webkit2gtk4.1-devel gtk3-devel sqlite-devel alsa-lib-devel \
openssl-devel libayatana-appindicator-gtk3-devel librsvg2-devel
# Arch Linux
sudo pacman -S webkit2gtk-4.1 gtk3 sqlite alsa-lib openssl \
libayatana-appindicator librsvg
# Alpine Linux
sudo apk add webkit2gtk-4.1-dev gtk+3.0-dev sqlite-dev alsa-lib-dev \
openssl-dev libayatana-appindicator-dev librsvg-dev- macOS:
xcode-select --install(WebKit is bundled) - Windows: MSVC C++ Build Tools + WebView2
git clone <repository-url> && cd pomotoro
just dev # starts Vite + Tauri with hot-reloadThe app opens automatically. Run just with no arguments to see every command.
- Start the timer — a default focus session is ready to go out of the box.
- Add tasks — quick-add or open the detail modal for tags, descriptions, and a custom session count.
- Focus — pick a task, hit play, and let ambient audio keep you in flow.
- Cycle tasks instantly with
Ctrl/Meta+Tab. - Take your break — the screen blocker (if enabled) makes sure you do.
- Tune everything in Settings → General / Timer / Notifications / Audio.
Start · Pause · Resume · Skip phase · Reset countdown · Reset task
All settings live in Settings and persist to local SQLite.
⏱️ Timer
- Focus, short-break, and long-break durations (minutes or seconds)
- Sessions until long break (2–10)
🤖 Automation
- Auto-start breaks after work
- Auto-start work after break
- Task cycling behavior:
ManualorAutoAdvance
🔔 Notifications
- Desktop notifications toggle
- Sound notifications toggle
- Phase-transition alerts
- Task-completion alerts
- Auto-dismiss delay (1–300s)
- On-screen position (4 corners + center)
🎵 Audio
- Master mute / volume
- Ambient background audio during work (rain, forest, ocean, white noise, café, fireplace, thunderstorm, brown noise)
- Separate work & break notification sounds (bell, chime, ding, gentle-bell, wooden-block)
- In-app Test preview for every sound
🎨 Appearance
- Theme: System / Light / Dark
🪟 Window & tray
- Minimize to system tray
- Start minimized
- Show countdown in tray tooltip
🚫 Screen blocking
- Block screen after work (with custom message)
- Block screen after break (with custom message)
All tasks run through just. The most common ones:
| Command | Description |
|---|---|
just dev / dev-debug / dev-trace |
Dev server at info / debug / trace logging |
just build |
Production build (lints, formats, then bundles) |
just serve-react |
Frontend-only dev server (no Tauri) |
just test |
All tests |
just test-domain / test-usecases / test-infra |
Per-layer tests |
just ci |
Full gate: test, check, fmt, clippy, react lint+typecheck |
just check · just fmt · just clippy · just check-react |
Targeted checks |
just clean |
Remove build artifacts |
just install-deps |
Linux system dependencies |
just install-hooks |
Install git pre-commit hook |
Falling back to cargo / npm
| Command | Description |
|---|---|
cd apps/tauri-app && cargo tauri dev |
Dev server |
cd apps/tauri-app && cargo tauri build |
Production build |
cd apps/react-ui && npm run dev |
Frontend only |
cargo test --workspace |
All tests |
cargo fmt --all · cargo clippy --workspace |
Format / lint |
cd core/infra
diesel migration run # apply
diesel migration revert # rollback last
diesel migration redo # rollback + reapplyjust build # or: cd apps/tauri-app && cargo tauri buildArtifacts land in target/release/bundle/:
- Linux:
.deb/.AppImage - macOS:
.dmg(universal — Intel + Apple Silicon) - Windows:
.msi/.exe(NSIS)
To cut a published release instead, see Cutting a release below.
Releases are tag-triggered. From a clean main:
just release VERSION=0.2.0This bumps the version in the shipping crates (apps/tauri-app/tauri.conf.json,
apps/tauri-app/Cargo.toml, apps/react-ui/package.json), commits, tags
v0.2.0, and pushes. The Release workflow then builds Windows, macOS
(universal), and Linux installers and attaches them to the GitHub Release
automatically — see CHANGELOG.md for the version history.
Pomotoro exists because I wanted a native desktop app with the feature set above — and nothing out there covered it cleanly without being Electron, closed-source, or freemium. So I built it, and it's free (MIT).
It also happens to be a sandbox for exploring Clean Architecture + DDD in Rust + Tauri, and for agentic AI-assisted development. Those shape the code but aren't the reason the app exists.
Full story: docs/MOTIVATION.md.
Pomotoro follows Clean Architecture + DDD. The core engine is fully framework-agnostic and reusable by any Rust client.
pomotoro/
├── core/ # Framework-agnostic core engine
│ ├── domain/ # Business logic & entities (Task, Timer, Session, Config, Audio)
│ ├── usecases/ # Application services (orchestrates domain)
│ └── infra/ # Infrastructure (repos, event bus, audio, timer tick)
│ # ⚠️ Zero Tauri dependencies — reusable by any client
└── apps/ # Client applications (thin wrappers over core)
├── tauri-app/ # Tauri desktop client (commands, plugins, UI emission)
├── react-ui/ # React + TypeScript frontend (Vite)
├── pomotoro-cli/ # CLI client (planned)
└── cosmic-de/ # Cosmic DE applet (planned)
Dependency direction (inward): UI → Infrastructure → Use Cases → Domain.
- Frontend: React + TypeScript, bundled with Vite
- Backend: Tauri desktop shell
- Languages: Rust (core/backend) · TypeScript (frontend)
- Persistence: SQLite via Diesel ORM with r2d2 pooling
- Async runtime: Tokio
Vite compiles the React/TypeScript frontend and serves hot-reload during dev. Tauri CLI embeds those static assets into a native window, exposes system APIs (notifications, tray, audio, screen blocking), and produces platform installers. Think of it like building the electric motor (Vite) before assembling the car (Tauri).
| Symptom | Fix |
|---|---|
error: no such subcommand: tauri |
cargo install tauri-cli |
pkg-config exited with status code 1 |
Missing GTK/Pango/GDK/ALSA/Soup libs — run just install-deps (Linux) |
library 'alsa' ... was not found |
Install libasound2-dev (Debian) / alsa-lib-devel (Fedora) |
library 'libsoup-3.0' was not found |
Install libsoup-3.0-dev |
| webkit2gtk build errors (Linux) | sudo apt install libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev |
-lsqlite3 not found during diesel_cli install |
Install libsqlite3-dev (or sqlite-devel / sqlite / sqlite-dev) |
| Frontend "Failed to load module" | cd apps/react-ui && rm -rf dist node_modules && npm install && npm run build |
After installing missing system libraries, run cargo clean then rebuild.
Planned features and direction. Items are exploratory and may shift based on feedback and contributor interest.
📊 Statistics — session-history timelines, daily / weekly / monthly summaries, streaks, per-task / tag / project breakdowns, charts & heatmaps, CSV / JSON export, and daily or weekly focus-time goals.
💻 Command-line interface — drive Pomotoro from the terminal: status & timer
control (start, pause, reset, skip), task management, config access, a
headless daemon mode, and shell completions for bash / zsh / fish / PowerShell.
⚡ Command hooks — run user-defined shell commands on lifecycle events
(timer.started, task.completed, phase.changed, …) with templated arguments
({phase}, {task}, {duration_seconds}), safe opt-in defaults, and a
diagnostics log view.
🔭 Longer-term explorations — end-to-end-encrypted cloud sync, a read-only mobile companion, user-built themes & visualizations, a plugin system, and a local focus-metrics API for integrations.
Full detail and latest status: ROADMAP.md.
- Fork →
git checkout -b feature-name - Develop —
just dev, test withjust test - Verify —
just cimust pass before pushing - Commit with clear messages and open a pull request
See the Roadmap for planned features, and docs/README.md for the full documentation index (architecture, reference, coding standards, and workflows).
MIT — see LICENSE.
- 🍅 Inspired by the Pomodoro Technique by Francesco Cirillo
- 🦀 Built with Tauri and React
- 🐂 Powered by the strength and speed of Rust