Nineteen interaction sounds for the web, synthesized live with Web Audio. No audio files, no dependencies.
npm install joeblau/soundESM-only, works in modern browsers. SSR-safe (imports are no-ops on the server).
Add attributes, call bind() once:
<button data-sound-press data-sound-release>Save</button>
<a data-sound-hover="tick">Docs</a>
<button data-sound-toggle>Dark mode</button>import { bind } from "sound";
bind();Or play sounds directly:
import { play, setEnabled } from "sound";
play("success");
setEnabled(false); // mute everythingWorks in any framework — React, Vue, Astro, plain HTML. Call bind() once after the DOM is ready.
Attributes:
| Attribute | Fires on | Default sound |
|---|---|---|
data-sound-hover |
pointerenter |
chime |
data-sound-press |
pointerdown |
press |
data-sound-release |
pointerup |
release |
data-sound-toggle |
click |
toggle |
Sounds:
chime · sparkle · droplet · bloom · whisper · tick · press · release · toggle · success · error · page · loading · ready · payout · deposit · pluck · notification · loss
API:
import { play, bind, setEnabled, sounds, type SoundName } from "sound";play(name?)— play a sound (default"chime"). Silent no-op on invalid names or blocked audio.bind(root?)— wire up alldata-sound-*attributes underroot(default: document). Idempotent; handles elements added later.setEnabled(enabled)— enable/disable playback.sounds— list of all sound names;SoundName— their union type.
MIT