DEV Community

aboagye Dunca
aboagye Dunca

Posted on

How I Built a Precise Browser Metronome (And Why setTimeout Wasn't Good Enough)

A deep dive into Web Audio API timing, and the surprising complexity behind a "simple" click.


The Problem With Online Metronomes

I play guitar. Not professionally — just a hobby I've had for years. Like most self-taught musicians, I knew I needed a metronome, and like most people in 2026, I reached for a browser-based one.

What I found was disappointing.

Most online metronomes fall into two categories: overly bloated apps with ads everywhere, or minimal tools that drift at higher tempos. Try setting one to 180 BPM and you'll hear it — the clicks start to feel uneven, rushed, then behind. It's subtle, but as a musician, you feel it.

So I decided to build my own: Tap Metronome.

Why JavaScript Timers Fail at Music

Here's something most web developers don't realize: setTimeout and setInterval are not accurate enough for music.

The browser's event loop is single-threaded. When you write:

setInterval(() => playClick(), 500); // 120 BPM
Enter fullscreen mode Exit fullscreen mode

You're asking the browser to schedule a callback approximately every 500ms. But if the main thread is busy — rendering, garbage collecting, handling a scroll event — that callback could fire 10ms, 30ms, or even 100ms late.

For a visual animation, 30ms of drift is invisible. For a metronome, it's the difference between "tight" and "sloppy."

The Solution: Web Audio API Scheduling

The Web Audio API has its own high-precision clock, separate from the main thread. It runs on a dedicated audio thread with sample-accurate timing.

The key insight is look-ahead scheduling: instead of playing sounds reactively, you schedule them ahead of time into the audio context's timeline.

The approach works like this:

  1. Use setInterval as a coarse "wake-up" call (~25ms interval)
  2. Each wake-up, calculate which beats fall within the next ~100ms window
  3. Schedule those beats using AudioContext.currentTime with precise timestamps
  4. The audio thread plays them at exactly the right moment
Main Thread:    |--wake--|--wake--|--wake--|--wake--|
Audio Thread:   tick.........tick.........tick.........
                 ^ scheduled ahead    ^ sample-accurate
Enter fullscreen mode Exit fullscreen mode

This two-tier architecture means the main thread can be janky, laggy, or busy — the clicks still land on time.

Beyond the Click: Features That Mattered

Once I had rock-solid timing, I focused on what musicians actually need during practice:

Multiple Time Signatures — Not everything is 4/4. Waltzes need 3/4, marches need 2/4, and many jazz and folk pieces use 6/8. The metronome accents the first beat of each measure for clear phrasing.

Subdivisions — Quarter notes, eighth notes, and triplets. When you're working on a fast passage, slowing down and subdividing is one of the most effective practice techniques.

Tap Tempo — Sometimes you hear a song and want to match its tempo. Tap along and the BPM calculates automatically.

Visual Beat Indicators — Especially useful when you can't or don't want to hear the click (late night practice with headphones, checking your internal timing).

Preset BPM Ranges — Quick access to common tempos: 60 BPM for slow practice, 120 BPM as the universal standard, genre-specific presets for rock, jazz, ballads, and more.

Lessons Learned

1. Audio on mobile is a minefield. iOS requires a user gesture before any audio can play. Android Chrome has its own quirks. I spent more time on cross-browser audio initialization than on any other single feature.

2. Less is more. My early versions had too many options visible at once. Musicians want to set a tempo and play, not configure a spaceship. Every UI element I removed made the tool better.

3. Performance tempo affects psychology. This was a rabbit hole I didn't expect to fall into. Research shows that tempos near 120 BPM feel "natural" to most humans — it matches a brisk walking pace. Below 60 BPM, music feels like it's dragging. Above 160, it becomes physically stimulating. I used these insights to inform the default settings and practice recommendations.

4. Internationalization matters for music tools. Musicians are everywhere. The app now supports English, Chinese, Japanese, Korean, and Spanish, with more planned.

Try It

Tap Metronome is free, runs entirely in your browser, no sign-up required. It works on desktop and mobile.

If you're a musician, I'd love to hear how it fits into your practice routine. If you're a developer, I'd welcome feedback on the Web Audio API implementation.


Have questions or feedback? Reach out at tapmetronome.app/contact.

Top comments (0)