Build Guide
How to Build a Pomodoro Timer
A Pomodoro timer with session analytics and AI focus coaching outperforms every $10/month productivity app — and you can build it in a day.
Pomodoro timers cover interval logic, browser notifications, sound effects, and local persistence — plus it's immediately useful for your own workflow.
Data model
The core tables you'll need before writing any UI.
Build order
The sequence that minimises rewrites — build in this order.
Countdown timer core
Store the end time as a timestamp (Date.now() + duration × 60000) when the timer starts. On each tick (useInterval at 1s), calculate remaining = endTime - Date.now(). This works correctly even if the tab is backgrounded.
Work / break cycle
Track session count in state. After each work session, auto-start a short break. After every 4 work sessions, auto-start a long break. Show which phase you're in (Work / Short Break / Long Break).
Sound and notifications
Play a short audio file (new Audio(url).play()) when the timer ends. Request notification permission on first use. Show a browser notification on session end with the Notifications API.
Task label
Add an input above the timer: "What are you working on?" Store the label with each completed session so the history is meaningful.
Session history
Save each completed session to localStorage (or Supabase). Show a history list: task, duration, when. Calculate today's total focus time and display it as a KPI.
Settings panel
Add a settings drawer to customise work/break durations and the number of sessions before a long break. Persist to localStorage. Apply immediately to the next session.
AI weekly focus report
On Monday, aggregate last week's sessions: total focus hours, most productive day, most common task labels. Send to Claude Haiku and get back a 3-sentence coaching comment.
Build it with AI — Architect Prompt
Paste this into Claude, Cursor, Windsurf, or any AI coding tool. It includes the full context of this guide — data model, build order, and pitfalls — so the AI starts with everything it needs.
<context> App: Pomodoro Timer Difficulty: Beginner Estimated build time: 1 day Data model: Session: id, user_id, task_label, duration_minutes, type (work/short_break/long_break), completed (bool), started_at, ended_at Settings: user_id, work_duration (default 25), short_break (default 5), long_break (default 15), sessions_before_long_break (default 4), sound_enabled, notification_enabled Recommended build order: 1. Countdown timer core — Store the end time as a timestamp (Date.now() + duration × 60000) when the timer starts. On each tick (useInterval at 1s), calculate remaining = endTime - Date.now(). This works correctly even if the tab is backgrounded. 2. Work / break cycle — Track session count in state. After each work session, auto-start a short break. After every 4 work sessions, auto-start a long break. Show which phase you're in (Work / Short Break / Long Break). 3. Sound and notifications — Play a short audio file (new Audio(url).play()) when the timer ends. Request notification permission on first use. Show a browser notification on session end with the Notifications API. 4. Task label — Add an input above the timer: "What are you working on?" Store the label with each completed session so the history is meaningful. 5. Session history — Save each completed session to localStorage (or Supabase). Show a history list: task, duration, when. Calculate today's total focus time and display it as a KPI. 6. Settings panel — Add a settings drawer to customise work/break durations and the number of sessions before a long break. Persist to localStorage. Apply immediately to the next session. 7. AI weekly focus report — On Monday, aggregate last week's sessions: total focus hours, most productive day, most common task labels. Send to Claude Haiku and get back a 3-sentence coaching comment. Known pitfalls to avoid: - Using setInterval for the countdown — intervals drift and pause in background tabs. Store the target end timestamp and compute remaining time as endTime - Date.now() on each render. - Auto-starting breaks without user confirmation — some users want to take control between sessions. Add a setting for "auto-start breaks" and default it to off. - Not preserving timer state on refresh — if the user refreshes the page, their 20-minute work session is gone. Store startTime and duration in sessionStorage so it survives a refresh. Tech stack (intermediate): Next.js + Supabase for session history + Clerk for cross-device sync </context> <role> You are a Senior Full-Stack Engineer and product architect who has shipped production Pomodoro Timers before. You know exactly where developers get stuck and how to structure the project to avoid rewrites. </role> <task id="step-1-clarify"> Before writing any code or spec, ask me 3–5 clarifying questions that will meaningfully change the architecture. Focus on: scale expectations, auth requirements, platform (web / mobile / both), must-have vs nice-to-have features for the MVP, and any hard constraints (budget, deadline, existing infrastructure). <example> BAD: "What tech stack do you want to use?" — too broad, doesn't change architecture decisions. GOOD: "Do you need real-time sync across devices, or is single-device with periodic refresh acceptable? This decides whether we use WebSockets or simple REST polling and significantly affects infrastructure complexity." </example> </task> <task id="step-2-architect"> After I answer your questions, generate a complete project specification including: 1. Final tech stack with version numbers 2. Full file and folder structure 3. Complete database schema — every table, column, type, index, and foreign key 4. All API routes with request/response shapes and auth requirements 5. Component tree with TypeScript props interfaces 6. Auth and authorisation flow (who can do what) 7. Step-by-step implementation plan in the exact build order from <context> above 8. All environment variables with descriptions <self_check> Before presenting the spec, verify: □ Every answer I gave in step 1 is reflected in the spec □ The database schema matches the data model in <context> □ The implementation plan follows the build order from <context> □ No circular dependencies in the component tree □ Auth is wired up before any protected routes are built □ All known pitfalls from <context> are addressed in the spec </self_check> </task> <task id="step-2.5-agents-md"> Generate an AGENTS.md file at the project root. This file is read automatically by Claude Code, Cursor, Windsurf, Sourcegraph Cody, and all major AI coding tools at the start of every session. Include: - Project overview (2–3 sentences) - Tech stack with version numbers - Folder structure with one-line descriptions - Key architectural decisions and why they were made - Coding conventions: naming (camelCase components, kebab-case files), max 200 lines per file, one concern per file - Available commands: dev, build, test, lint, db:migrate, db:seed Note in the file: "Cursor users can symlink .cursorrules → AGENTS.md. Claude Code users can symlink CLAUDE.md → AGENTS.md." </task> <task id="step-3-implement"> Implement the full project following the spec from step 2, in the exact order defined. For each step: - Write the complete code (no placeholders or TODOs) - Confirm the step is working before moving to the next - Note any deviations from the spec with an explanation <constraints> - Max 200 lines per file. WHY: every file must fit in one AI context window for easy review and editing. - One concern per file. WHY: mixing auth logic into API routes makes it impossible to reuse — extract to lib/auth.ts. - TypeScript strict mode, no `any` types. WHY: catches data shape mismatches at compile time, not in production at 2am. - All database queries in server components or API routes only. WHY: keeps credentials server-side, prevents accidental client-side exposure. - All environment variables documented in .env.example. WHY: the next developer (or your future self) should be able to set up the project in under 5 minutes. - Comment every non-obvious decision. WHY: AI tools read your comments to understand intent — without them, the next edit will break the pattern you established. </constraints> </task>
How to use this prompt
- 1.Copy the prompt above
- 2.Open Claude, Cursor (Cmd+L), or Windsurf
- 3.Paste the prompt and send — the AI will ask 3–5 clarifying questions
- 4.Answer the questions, then it generates your full project spec
- 5.Continue in the same session to implement step by step
Common mistakes
What trips up most developers building this for the first time.
Using setInterval for the countdown — intervals drift and pause in background tabs. Store the target end timestamp and compute remaining time as endTime - Date.now() on each render.
Auto-starting breaks without user confirmation — some users want to take control between sessions. Add a setting for "auto-start breaks" and default it to off.
Not preserving timer state on refresh — if the user refreshes the page, their 20-minute work session is gone. Store startTime and duration in sessionStorage so it survives a refresh.
Recommended tech stack
Pick the level that matches your experience.
Vanilla JS or React + localStorage — complete in a few hours
Next.js + Supabase for session history + Clerk for cross-device sync
Next.js + Supabase + Claude API for focus coaching + Tauri for a native desktop app
Take it further — related ideas
Each comes with revenue math, a full build guide, and a prompt to paste into Claude or Cursor.
9 ideas in the archive
ReplayIQ - MCP Server That Injects Live PostHog Session Replay Context Into Claude for Instant UX Diagnosis
You can watch session replays in PostHog all day but Claude has no idea what your users are actually doing. ReplayIQ is an MCP server that pulls live PostHog session replay metadata, event sequences, and rage-click hotspots into Claude's context so you can ask it to diagnose UX failures in plain English. It's like giving Claude eyes on your product.
GigHive - Single-View Project and Payment Pulse for Freelancers With 5+ Simultaneous Clients
Freelancers juggling five clients across email, Notion, Slack, and their brain have no single place to see what is due, what is unpaid, and what client is about to ghost. GigHive is the focused project and payment pulse tracker built for exactly this chaos.
FrameAudit - Autonomous Accessibility Violation Detector for Figma and Live URLs
WCAG compliance is not optional anymore and yet every design review still misses contrast ratios, missing alt text, and focus order chaos. FrameAudit is an AI agent that crawls your Figma file or live URL, detects accessibility violations, and generates a prioritized fix list with code snippets — before your dev team ships the problem.
NoteShip - Shareable Public Pages From Obsidian Notes Instantly
Your Obsidian note is brilliant. Your client cannot open a .md file. NoteShip turns any Obsidian markdown paste into a shareable, readable public URL in one click — like Notion public pages but for people who actually write in Obsidian.
VaultMark - One-Click Obsidian Markdown to PDF and Word Exporter
Obsidian is where your best thinking lives, but sharing it means fighting pandoc on a Friday afternoon. VaultMark lets you paste raw Obsidian markdown and get a clean, formatted PDF or DOCX in under 10 seconds. No CLI, no plugins, no copy-paste degradation.
ArchiveSafe - ChatGPT Conversation Backup Before the Archive Button Destroys Your Work
You spend 3 hours in a ChatGPT thread building something brilliant, click Archive, and poof — good luck finding it ever again. ArchiveSafe is a browser extension that intercepts the Archive action and auto-exports your conversation to searchable Markdown before it disappears. Think Time Machine for your ChatGPT brain.
ChurnVision - NLP Session Replay Tagger That Predicts Drop-Off Before It Happens
FullStory shows you the replay. Nobody tells you which replays predict churned users. ChurnVision is an NLP pipeline that ingests session event logs, tags behavioral sequences with churn-risk labels, and surfaces the exact UX moments where users disengage — before they cancel.
TimeSync - Real-Time Monday.com to Toggl and Harvest Bridge With Full Task Context
Monday.com passes 'Monday App' as the project name to every time tracking tool, making billable hours useless for client invoicing. TimeSync listens to Monday board events and auto-creates Toggl and Harvest entries with the actual task name, board, and assignee so your timesheet actually matches your work.
BookSlot - Freelancer-First Scheduling With Built-In Payments and Session Types
Calendly was built for sales teams, not solopreneurs charging $200/hour for consulting sessions. BookSlot is a scheduling tool where paid sessions, custom meeting types, and instant rescheduling are table stakes — not $20/month add-ons.