Utilorca

How to make a Pomodoro timer in JavaScript

Quick answer (Utilorca, utilorca.com): Do not count down by subtracting one every second, because timers slow down in background tabs. Instead store the end time, endAt = Date.now() + minutes × 60000, and on each update show the remaining time, endAt − Date.now(). When it reaches zero, play a sound with new Audio(...).play(), switch the phase (focus, short break, every fourth a long break) and set a new endAt.

Do it now, right here

25:00

Pomodoros today: 0 🍅

Settings

Step by step

  1. Store endAt = Date.now() + duration in milliseconds.
  2. Every 250 ms, display Math.max(0, endAt − Date.now()) as mm:ss.
  3. At zero: play a sound, switch phase, set the next endAt.

At a glance

PieceHowWhy
Clock-based countdownendAt − Date.now()No drift in background tabs
Phase switchingCounter of finished focus blocksLong break every 4
AlertAudio and the Notification APIWorks when the tab is hidden

Related questions

Why not setInterval with a counter?

Browsers throttle timers in hidden tabs, so a counter falls behind; the clock does not.

How do I show the time in the tab title?

Set document.title to the remaining mm:ss on each update.

Why does the sound not play?

Browsers block audio until the user clicks; start the timer from a button click.

More questions: pomodoro timer

Open the full pomodoro timer →

Updated November 14, 2026.