npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dougflip/metronome

v0.0.3

Published

Headless metronome with events

Readme

Metronome

A headless metronome built on top of the Web Audio API.

npm install @dougflip/metronome

Basic Usage

Plays a "click" sound on each beat using the Web Audio API. Allows you to update the tempo and volume after creation.

import { createMetronome } from "@dougflip/metronome";

const metronome = createMetronome({
  tempo: 60, // as beats per minute
  beatsPerBar: 4,
  volume: 50, // value from 0-100
});

// the Web Audio API requires a user event to trigger sound!
// make sure you call `start` in response to a user event
function handleMetronomeStartClick() {
  metronome.start();
}

// Update tempo or volume - from form control inputs for example
function handleMetronomeUpdate({ tempo, volume }) {
  metronome.updateConfig({ tempo, volume });
}

// sometime later, when you are done
function handleMetronomeStopClick() {
  metronome.stop();
}

Events

There are also several supported events which can be configured

  • onBeatStart: A callback that fires at the start of each beat. Useful to trigger visual cues or other events.

  • beatInterval: A configuration that allows you to set a specific interval of beats to trigger an event. For example, you can set it to fire every 4 beats.

  • maxBeats: A configuration that allows you to set the total number of beats before the metronome stops automatically. This includes an optional onEnd callback that fires when the metronome stops.

import { createMetronome } from "@dougflip/metronome";

const metronome = createMetronome({
  tempo: 60,
  volume: 50,
  beatsPerBar: 4,

  // fires on every beat
  //   - `beatsPerBar`: beat number relative to `beatsPerBar`
  //   - `totalBeats`: total number of beats since start
  onBeatStart: ({ beatNumber, totalBeats }) =>
    console.log({ beatNumber, totalBeats }),

  // fire an event every 4 beats - starting on beat 1.
  // in this case, beats 1, 5, 9, etc., corresponding to the start of every measure
  beatInterval: {
    count: 4,
    onBeatInterval: ({ currentInterval }) => console.log(currentInterval),
  },

  // play for a maximum of 10 measures (4 beatsPerBar times 10 measures)
  // the last beat will last its full length and then `onEnd` will fire
  maxBeats: {
    count: 4 * 10,
    onEnd: () => console.log("metronome has stopped"),
  },
});

Local Development

# select correct node
nvm use

# install deps
npm install

# build the code
npm run build

# verify the code and build
npm run check

Tests

👷 Under construction 👷

I think the state management logic could be better extracted and unit tested. But short term, I am more interested in trying to write some functional tests where we actually run the code in a real browser and verify it. That is likely where I will start.

Inspiration and Credit

An original version of this metronome was based upon:

  • https://github.com/grantjames/metronome
  • https://grantjam.es/creating-a-simple-metronome-using-javascript-and-the-web-audio-api/

This version was built using the same principles but adds events and state tracking. Most of the actual code was written by Claude.ai

License

This project is licensed under the MIT License. See the LICENSE file for details.