⏱️ Stopwatch

🔧 Controls

Status: {{ running ? 'running' : (elapsedMs > 0 ? 'paused' : 'idle') }}
Laps recorded: {{ laps.length }}

ℹ Tips

  • Start begins counting from zero or resumes from a paused value.
  • Pause freezes the elapsed value without clearing laps; press Start to resume.
  • Lap records the current split and the delta from the previous lap.
  • Reset zeroes everything and clears every recorded lap.

⏱ Elapsed

{{ formattedElapsed }}

Always HH:MM:SS.mmm. Hour padding is dropped once the count exceeds 99 hours so very long runs render cleanly.

🚩 Laps

  1. {{ 'Lap ' + row.number }}: {{ row.lapFormatted }} (split {{ row.splitFormatted }})

ℹ️ About Stopwatch

What this tool does

The Stopwatch counts up from zero with millisecond precision. Hit Start to begin, Lap to record a split, Pause to freeze the elapsed value, and Reset to clear everything. The display always shows the full HH:MM:SS.mmm form so you can see fractional seconds at a glance. Laps are listed newest-first with both the lap delta and the running split for that lap.

How it works (technical details)

  • Pure client-side. Elapsed time, lap math, and the rendered display are all computed inside your browser. No network request is made, and no data leaves the page.
  • Monotonic clock. The stopwatch uses performance.now(), a high-resolution monotonic timestamp that is not affected by user-initiated wall-clock changes, NTP corrections, or daylight-saving transitions. Date.now() can jump backwards; performance.now() cannot, which is why it is the right primitive for a stopwatch.
  • Per-frame update. The elapsed value is recomputed every animation frame via window.requestAnimationFrame. Background tabs throttle that callback, but the next visible frame still reads a fresh timestamp so the display catches up instead of drifting.
  • Pause/resume math. Pause folds the current elapsed value into an accumulated bucket and clears the start timestamp. Start re-captures performance.now() and the rAF loop reports (now − startedAt) + accumulated from then on, so the displayed value continues from where it stopped.
  • Lap math. Each lap stores the split (total elapsed at the moment Lap was pressed) and the lap delta (split minus the previous lap's split). The ISO timestamp recorded with each lap is the wall-clock instant from Date.now(), used only as a human-readable annotation; the stopwatch arithmetic itself never touches Date.now().

Use cases

  • Workout intervals — count up through a HIIT round and record per-rep splits.
  • Pair sessions and focus blocks — visible running time during a coding sprint or a meeting timebox.
  • Benchmarking — quick wall-clock sanity check for a manual operation when a dedicated benchmark harness would be overkill.
  • Cooking and brewing — multi-stage timing with explicit lap markers between steps.
  • Race-style splits — record lap times during a run, ride, or game with newest lap shown first.

Privacy note

Every measurement, every lap, and every formatted display value lives inside this page. No elapsed time, no lap data, and no timestamps are sent to a server. There is no API endpoint for this tool — the algorithm is trivial and the interesting behavior is entirely in your browser.

References

Ready