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

zsk-use-sound

v1.0.1

Published

A TypeScript-first React hook for sound effects, inspired by the excellent `use-sound` package and extended with a browser-generated fallback mode.

Readme

zsk-use-sound

A TypeScript-first React hook for sound effects, inspired by the excellent use-sound package and extended with a browser-generated fallback mode.

Why this package

This hook gives you one API for two sound strategies:

  • File mode: Use audio files (mp3, wav, etc.) powered by Howler.
  • Generated mode: If no file is provided, it generates a click-like sound in the browser using the Web Audio API.

This is useful when you want sound feedback but do not always want to bundle and manage sound assets.

Installation

bun add zsk-use-sound

or

npm install zsk-use-sound

Peer dependency:

  • React 18+

Quick Start

import { useSound } from 'zsk-use-sound'

export function SaveButton() {
  const [play] = useSound({
    file: '/sounds/click.mp3',
    volume: 0.5,
  })

  return <button onClick={() => play()}>Save</button>
}

API

useSound(options?)

Returns a tuple:

  • play: function to trigger sound playback
  • exposedData: helper controls and runtime metadata
const [play, exposedData] = useSound(options)

Options

type BuiltInSoundType = 'click' | 'soft-click' | 'tick'

interface UseSoundOptions {
  file?: string | string[]
  type?: BuiltInSoundType
  id?: string
  volume?: number
  playbackRate?: number
  interrupt?: boolean
  soundEnabled?: boolean
  sprite?: Record<string, [number, number]>
  onload?: (this: Howl) => void

  // Plus delegated Howler options
}

Behavior:

  • If file is passed: hook runs in file mode using Howler.
  • If file is omitted: hook runs in generated mode and uses built-in Web Audio click profiles.
  • Default type is click.

play(options?)

interface PlayOptions {
  id?: string
  forceSoundEnabled?: boolean
  playbackRate?: number
}

Exposed data

interface ExposedData {
  sound: Howl | null
  stop: (id?: number) => void
  pause: (id?: number) => void
  duration: number | null
  mode: 'file' | 'generated'
}

Usage Patterns

1) File mode (use-sound style)

import { useSound } from 'zsk-use-sound'

export function NotificationButton() {
  const [play, { stop, mode }] = useSound({
    file: ['/sounds/ping.wav', '/sounds/ping.mp3'],
    volume: 0.4,
    interrupt: true,
  })

  return (
    <>
      <button onClick={() => play()}>Play</button>
      <button onClick={() => stop()}>Stop</button>
      <small>mode: {mode}</small>
    </>
  )
}

2) Generated mode (no file)

import { useSound } from 'zsk-use-sound'

export function UIInteractions() {
  const [play, { mode }] = useSound({
    type: 'soft-click',
    volume: 0.6,
  })

  return <button onClick={() => play()}>Click me ({mode})</button>
}

3) Global sound toggle

import { useSound } from 'zsk-use-sound'

export function MutedAwareAction({ isEnabled }: { isEnabled: boolean }) {
  const [play] = useSound({
    file: '/sounds/action.mp3',
    soundEnabled: isEnabled,
  })

  return <button onClick={() => play()}>Action</button>
}

Why Howler

Howler is used for file playback mode because it offers:

  • Cross-browser audio consistency: normalizes browser differences.
  • Flexible source handling: supports source arrays and format fallback.
  • Sprite support: multiple sounds in one file with IDs.
  • Stable playback controls: volume, rate, stop, pause, and event hooks.
  • Mature ecosystem: widely used and battle-tested.

In short, Howler handles the hard edges of browser audio so your hook API stays simple.

How this package is better for this use case

Compared to a direct baseline implementation, this package adds:

  • Dual-mode behavior: file-based audio plus generated fallback in one hook.
  • No-any TypeScript API: explicit options and return types.
  • Better type surface for consumers: exported public types directly from the package.
  • Built-in sound presets: click, soft-click, tick.
  • Runtime mode visibility: exposedData.mode tells you how playback is happening.

Credit

This package is inspired by:

  • Josh Comeau's original use-sound project: https://github.com/joshwcomeau/use-sound

Many API ideas (tuple return shape, play options, exposed control object, and Howler-based file mode approach) are adapted from that excellent work.

Thank you to Josh Comeau for creating and sharing the original library.

TypeScript Exports

You can import runtime and type APIs directly:

import { useSound } from 'zsk-use-sound'
import type {
  BuiltInSoundType,
  UseSoundOptions,
  PlayOptions,
  ExposedData,
  ReturnedValue,
} from 'zsk-use-sound'

Notes

  • Generated mode relies on Web Audio API availability in the browser.
  • Browsers often require user interaction before sound can play.
  • For SSR environments, playback happens client-side only.

License

ISC