Track tasks, routines or run pomodoros in a Progressive Web Application.
A timer built to be read across a room while your hands are busy: giant digits, colour-coded phases, audible cues. Installable, works fully offline, keeps accurate time when the screen sleeps.
Status: specified, not yet built. The design is settled in
docs/spec.md; implementation has not started.
Three capabilities, not a menu of modes:
| Capability | What it does |
|---|---|
| Count up | An unbounded chrono — start, pause, reset |
| Count down | From a duration you set on the timer itself |
| Repeat | Work, optional rest, a number of rounds |
Tabata, EMOM and Pomodoro are configurations you build, not features the app ships: 20s / 10s × 8 is a Tabata whether or not anything is labelled "Tabata".
- Accurate by construction — state is derived from a wall-clock timestamp with a pure
phaseAt(elapsed, routine); nothing accumulates ticks, so nothing drifts. - Offline-first — precached service worker, no backend, no accounts, no analytics. Installable as Timer; waiting updates apply immediately when no Routine is active.
- Automatic updates — an active or paused Routine defers a waiting worker until Done or Reset. The new build reloads automatically; releases show green NEW vx.x.x at right, while dev previews append green NEW to the PR/deployment clue at left.
- Progressive enhancement — audio session, Wake Lock and vibration are feature-detected and no-ops where absent. The app is fully correct without any of them.
- Semantic and accessible — Pico CSS classless, WCAG 2.2 AA in every slice.
- No framework — plain Astro, TypeScript, CSS and DOM APIs. No React unless something proves it mandatory.
pnpm install
pnpm dev # http://localhost:4321| Command | Action |
|---|---|
pnpm dev |
dev server |
pnpm build |
production build to ./dist/ |
pnpm preview |
preview the build locally |
pnpm check |
astro check (types) + oxlint + oxfmt |
pnpm format |
oxlint --fix + oxfmt --write |
pnpm test |
vitest (unit) |
pnpm test:coverage |
vitest with a coverage report and 90% global thresholds |
pnpm check:dependencies |
fail when patch updates are available |
pnpm check:audit |
fail on high/critical npm advisories |
Git hooks: pre-commit formats and type-checks staged files, pre-push runs pnpm check && pnpm test.
Dependency drift and audit checks run in CI rather than pre-push, because they depend on external
registry/advisory state and can block unrelated local work.
package.json pins nanoid to 3.3.18 through pnpm.overrides. It is a transitive build-time
dependency of @vite-pwa/astro → vite-plugin-pwa → vite → postcss; the lockfile can otherwise keep
resolving vulnerable nanoid@3.3.17, even though the application does not ship nanoid to users.
The override stays until the dependency graph resolves nanoid >=3.3.18 without it. Verify with:
pnpm why nanoid
pnpm auditDecisions live in docs/spec.md, with code structure in docs/architecture.md. CONTEXT.md is the glossary. Future work lives in GitHub Issues: countdown → rounds.
Two branches are kept as primary sources and are deliberately not merged:
prototype/timer-ui— the UI prototype that chose the running-screen layout.research/pwa-platform— cited platform research (Wake Lock, WebAudio, install,@vite-pwa/astro).
Pull requests deploy preview builds to Netlify. Production deploys only when a GitHub Release is published, served at timer.marcosgilf.com.
Release Please opens Release PRs from Conventional Commits. Merging a Release PR bumps
package.json, updates CHANGELOG.md, creates a vX.Y.Z Git tag and a GitHub Release. Publishing
that release triggers the production deploy. The app shows that version in the bottom-right corner;
production update highlights stay there, while preview highlights use the left deployment clue.
Use commit prefixes intentionally:
feat:→ minor versionfix:→ patch versionfeat!:orBREAKING CHANGE:→ major versiondocs:/chore:→ no release unless paired with releasable changes
RELEASE_PLEASE_TOKEN is managed by infra/github and is required; Release Please PRs and releases
must trigger CI/deploy like human-created ones.
See CONTRIBUTING.md. Licensed under MIT.