A native macOS study session app that puts every tool you need — timer, notes, tasks, music, ambient sound, and calendar — in one persistent window. No alt-tabbing, no lost focus.
Platform: macOS 13+
- Pomodoro timer — focus/break cycles with macOS notifications
- Tasks — lightweight to-do list with tags
- Notes — markdown editor backed by
.mdfiles on disk - Spotify — remote control your Spotify playback via the Web API (Premium required)
- Ambient sound — mix rain, cafe, fireplace, and white noise
- Calendar — import
.icsfiles and view your agenda
graph TD
subgraph Frontend ["Frontend (React + TypeScript)"]
UI[Panels: Strip / Tasks / Notes / Calendar]
Stores[Zustand Stores]
Hooks[Event Hooks]
UI --> Stores
Hooks --> Stores
end
subgraph IPC ["Tauri IPC Boundary"]
Invoke["invoke() — commands"]
Listen["listen() — events"]
end
subgraph Backend ["Backend (Rust)"]
Pomodoro[pomodoro\nstate machine + tick loop]
Tasks[tasks\nCRUD]
Notes[notes\nfile I/O]
Spotify[spotify\nOAuth PKCE + Web API]
Ambient[ambient\nrodio audio mixer]
Calendar[calendar\n.ics parser]
Prefs[preferences\nkey-value store]
DB[(SQLite\nsbox.db)]
FS[(Disk\nnotes/*.md\ntokens.json)]
end
Stores -->|invoke| Invoke
Invoke --> Pomodoro & Tasks & Notes & Spotify & Ambient & Calendar & Prefs
Pomodoro & Tasks & Notes & Spotify & Ambient & Calendar & Prefs -->|emit events| Listen
Listen --> Hooks
Tasks & Calendar & Prefs --> DB
Notes --> FS
Spotify -->|tokens| FS
- Domain layout — every backend domain follows a 4-file shape:
mod.rs(commands),state.rs(types),service.rs(logic),store.rs(persistence). Domains don't cross into each other's internals. - IPC — frontend calls
invoke()for commands andlisten()for push events. Zustand stores update optimistically from command return values; events are a safety net. - Ambient audio —
rodiois notSend + Sync, so audio runs on a dedicatedstd::threadthat owns all sinks and communicates via a channel. - SQLite — WAL mode, single
Mutex<Connection>shared across tokio tasks.
| Data | Location |
|---|---|
| Tasks, Calendar, Preferences | ~/Library/Application Support/sbox/sbox.db |
| Notes | ~/Library/Application Support/sbox/notes/*.md |
| Spotify tokens | ~/Library/Application Support/sbox/tokens.json |
| Ambient audio | Bundled in .app/Contents/Resources/audio/ |
- Rust (stable)
- Node.js 20+
- Tauri CLI prerequisites for macOS (Xcode Command Line Tools)
npm installnpm run tauri devnpm run tauri buildThe .dmg and .app will be in src-tauri/target/release/bundle/.
sbox uses Spotify's Web API with PKCE — no client secret is stored. To connect:
- Create an app at developer.spotify.com
- Add
http://127.0.0.1:8888/callbackas a redirect URI - Put your Client ID in the app config
- Click "Connect Spotify" in the app and log in
Spotify Premium is required for playback control.
| Layer | Technology |
|---|---|
| Desktop shell | Tauri 2 |
| Backend | Rust, Tokio, rusqlite, reqwest, rodio |
| Frontend | React 19, TypeScript, Tailwind CSS v4 |
| State | Zustand |
| Editor | Tiptap (ProseMirror) |
| Build | Vite |