Skip to content

Repository files navigation

Tauri Clocks — Fully vibe coded with Claude. Every line of code was generated by AI. My role was limited to guiding the process and making decisions.

A lightweight, cross-platform (Windows / macOS / Linux) desktop clock application inspired by GNOME Clocks, built with Tauri v2 and Svelte 5 (Runes).

image

Features

  • ⏱️ Stopwatch — high-precision, backend-driven (Rust monotonic clock) ✅
  • ⏲️ Timer — countdown with looping alarm sound and blinking ring on finish ✅
  • 🎨 Light/dark theme — manual toggle, OS preference as default, persisted choice ✅
  • 🪟 GNOME-style window — undecorated, rounded corners, custom header bar ✅
  • 🚀 Minimal RAM/CPU footprint and small executable size

Architecture

All time-critical logic lives in the Rust backend:

  • Timing threads use std::time::Instant (monotonic clock), immune to system clock changes.
  • Shared state is managed through tauri::State guarded by std::sync::Mutex + Condvar.
  • The backend pushes elapsed time to the frontend via Tauri events (emit) at a rate matched to what each view renders: 10 Hz for the stopwatch, 5 Hz for the timer — and not at all while the window is hidden — keeping webview CPU minimal.
  • The frontend never uses setInterval / setTimeout to measure time — it only reacts to backend events and calls Tauri commands (invoke) for user actions.
  • Emitter threads sleep on a condition variable while idle → 0% CPU when unused.
┌─────────────────────────┐      events (emit 100–200 ms)      ┌──────────────────────┐
│      Rust backend       │ ─────────────────────────────────▶ │  Svelte 5 frontend   │
│  (threads, Instant,     │                                    │  (Runes: $state,     │
│   Mutex/Condvar state)  │ ◀───────────────────────────────── │   $derived, $effect) │
└─────────────────────────┘     commands (start/pause/reset)   └──────────────────────┘

Project structure

tauri-clocks/
├── README.md
├── BUILD.md                      # Build & dependency installation guide
├── AUDIO.md                      # How to replace the embedded alarm sound
├── PROMPT.md                     # Full specification prompt for this project
├── audio.ogg.base64              # Alarm sound (Ogg Vorbis, base64-encoded)
├── package.json                  # Frontend dependencies & scripts (step 2)
├── vite.config.ts                # Vite + Svelte plugin config (step 2)
├── svelte.config.js              # Svelte 5 compiler options (step 2)
├── tsconfig.json                 # TypeScript config (step 2)
├── index.html                    # Vite entry HTML (step 2)
├── dist/                         # Built frontend (generated; placeholder for now)
├── src/                          # ───────── Frontend (Svelte 5, Runes only) ─────────
│   ├── main.ts                   # Applies the theme, mounts the Svelte app
│   ├── App.svelte                # Rounded window frame, header bar, view switching
│   ├── assets/
│   │   └── dark-light.png        # Theme toggle icon (rendered via CSS mask)
│   ├── styles/
│   │   └── app.css               # GNOME-like design tokens, light/dark themes
│   └── lib/
│       ├── types.ts              # Shared TS types mirroring Rust event payloads
│       ├── stores/               # Runes-based state modules (.svelte.ts)
│       │   ├── stopwatch.svelte.ts
│       │   ├── timer.svelte.ts
│       │   └── theme.svelte.ts   # Light/dark theme manager (persisted)
│       └── components/
│           ├── Stopwatch.svelte
│           ├── Timer.svelte      # Duration picker + countdown progress ring
│           └── shared/
│               ├── TabBar.svelte
│               ├── TimeDisplay.svelte
│               ├── ControlButton.svelte
│               ├── ThemeToggle.svelte
│               └── WindowControls.svelte
└── src-tauri/                    # ───────── Backend (Rust + Tauri v2) ─────────
    ├── Cargo.toml                # Crate manifest + size/speed release profile
    ├── build.rs                  # Tauri build script
    ├── tauri.conf.json           # Tauri v2 app configuration
    ├── capabilities/
    │   └── default.json          # Permission capabilities for the main window
    ├── icons/                    # App icons (replace with `tauri icon`)
    └── src/
        ├── main.rs               # Desktop entry point (delegates to lib.rs)
        ├── lib.rs                # Builder setup, state registration, command handler
        ├── stopwatch.rs          # High-precision stopwatch ✅
        └── timer.rs              # Countdown timer + native notification ✅

Development

npm install          # install frontend dependencies
npm run tauri dev    # run in development mode
npm run tauri build  # build optimized release bundles

See BUILD.md for full instructions: per-platform dependency installation, artifact locations, and troubleshooting.

To replace the timer alarm sound, see AUDIO.md — the audio is embedded at compile time from audio.ogg.base64.

Backend ⇄ Frontend contract

Stopwatch

Kind Name Direction Payload
Event stopwatch://tick Rust → JS { elapsed_ms: number, running: boolean }
Command start_stopwatch JS → Rust
Command pause_stopwatch JS → Rust
Command reset_stopwatch JS → Rust
Command get_stopwatch_state JS → Rust returns { elapsed_ms, running }

Timer

Kind Name Direction Payload
Event timer://tick Rust → JS { remaining_ms, duration_ms, running, finished }
Command start_timer JS → Rust { durationMs: number }
Command pause_timer JS → Rust
Command resume_timer JS → Rust
Command reset_timer JS → Rust
Command get_timer_state JS → Rust returns { remaining_ms, duration_ms, running, finished }

When the countdown reaches zero, the backend sets the finished flag in the tick payload; the frontend reacts by looping the embedded alarm sound and blinking the progress ring until the user presses Reset.

License

MIT

About

A lightweight, cross-platform (Windows / macOS / Linux) desktop clock application inspired by GNOME Clocks, built with Tauri v2 and Svelte 5 (Runes).

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages