Cross-platform desktop eye care app — quiet, smart, out of your way
English | 简体中文
Eyezen is a lightweight desktop companion that protects your eyes without breaking your flow. It applies the 20-20-20 rule — every 20 minutes look ~6 m away for 20 seconds — and offers a Pomodoro alternative for deep-work sessions. Smart skipping during fullscreen apps, AFK periods, or whitelisted processes keeps reminders unobtrusive; built-in statistics and health analysis show whether the habit is actually sticking.
| Resting | Tip Window |
|---|---|
| Settings | About |
|---|---|
| Overview · Eye-Care Index · 24h Ribbon | Daily / Weekly / Monthly Trend |
|---|---|
Configurable focus / short break / long break cycle alongside 20-20-20
Requirements: Node.js v18+, Rust (stable), platform-specific dependencies per Tauri v2 Prerequisites.
git clone https://github.com/rsecss/eye-zen.git
cd eye-zen
npm install
npm run tauri dev # Development mode (hot reload)
npm run tauri build # Production build → src-tauri/target/release/bundle/
Run all 8 local CI checks (fmt, clippy, cargo test, svelte-check, vitest, prettier, build, version sync) in one shot:
npm run ci
| Layer | Choice | Description |
|---|---|---|
| Framework | Tauri v2 | Rust backend + native WebView |
| Frontend | Svelte 5 | Runes reactivity, zero runtime |
| Build | Vite 6 | Fast HMR, multi-entry windows |
| Styling | TailwindCSS v4 | Utility-first |
| Charts | ECharts | Tree-shaken, lazy-loaded |
| Database | SQLite via sqlx | Statistics persistence |
| Config | TOML | Human-readable |
| Audio | rodio | Rust-native, dedicated thread |
| Type Bridge | ts-rs | Rust → TypeScript auto-generation |
┌────────────────────────────────────────────────────────────┐
│ Frontend (Svelte 5) │
│ Windows: main · tray-panel · tip-window · tip-minimal │
│ invoke() ─→ Tauri Commands (thin layer) │
│ listen() ←─ Typed Events (ts-rs bindings) │
└────────────────────────────────────────────────────────────┘
│
┌────────────────────────────────────────────────────────────┐
│ Backend Services (Tauri State · 9 Arc-shared services) │
│ Config · Timer · Detector · Window · Sound │
│ Tray · I18n · Stat · Hotkey │
│ Communication: watch channels + EffectSink trait │
└────────────────────────────────────────────────────────────┘
│
┌────────────────────────────────────────────────────────────┐
│ Platform Layer — PlatformApi trait │
│ Windows · macOS · Linux X11/Wayland │
│ Capabilities: fullscreen detect · idle · foreground proc │
└────────────────────────────────────────────────────────────┘
Arc<AppServices> Tauri state; they communicate through typed tokio::sync::watch channels and an EffectSink trait so the timer state machine stays pure.PlatformApi trait with per-capability degrade flags — the Settings UI greys out toggles whose capability is unavailable (e.g. AFK on Wayland).ts-rs and centralized in src/lib/bindings/, eliminating a class of Rust↔TS drift bugs..trellis/spec/ are the canonical source for layering, IPC, and platform conventions — read them before contributing.Config is stored as config.toml in the system app data directory; the statistics database data.db lives alongside it.
| Platform | Path |
|---|---|
| Windows | %APPDATA%\com.eyezen.app\ |
| macOS | ~/Library/Application Support/com.eyezen.app/ |
| Linux | ~/.config/com.eyezen.app/ |
All settings can be modified through the in-app Settings UI — you should never have to edit the TOML by hand.
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.