Bringing Sound Back to the Web with a React Hook
Sound on the web has a bad reputation, and for good reason. From MIDI background music on early sites to autoplaying videos and malware popups, audio has often been used in the most intrusive ways possible. But used tastefully, sound can be a powerful tool for user feedback: it can accentuate actions, confirm input, and make an interface feel more responsive and tangible.
This isn't a novel concept—video games and mobile apps have relied on audio cues for decades. The web is the outlier in digital media for avoiding sound altogether. For a UI to deliver true confirmation, it shouldn't rely solely on visuals.
The use-sound Hook
To make it easier to integrate audio into React projects, a new hook called use-sound is now available on NPM. It was extracted from the author's own blog, where many UI controls produce subtle sounds on interaction.
The hook adds roughly 1kb (gzip) to your bundle and asynchronously loads a 10kb third-party dependency, Howler. It provides several built-in features, including:
- Stop, pause, and resume playback.
- Support for audio sprites, allowing a single file to be split into multiple sounds.
- Playback rate control to speed up or slow down effects.
- Access to Howler's extensive event listener system and advanced options.
Setting Up
Install the package with your preferred package manager:
bash npm install use-soundThen import the hook as the default export:
js import useSound from 'use-sound';Next, you'll need to import the audio files themselves. If you're using a tool like create-react-app or Gatsby, you can import MP3 files just like you would import images:
If you're using a custom Webpack configuration, you'll need to use file-loader to handle .mp3 files as arbitrary assets. Alternatively, you can reference static files relative to your public or static directory.
Finding and Prepping Audio Assets
The hook is only half the equation; you also need quality audio samples. Freesound.org is a strong resource, offering a large index of Creative Commons Zero licensed sounds. While an account is required for downloads, the files are free to use.
Before using these files, you'll likely need to tidy them up with a tool like Audacity, which is free and open-source. Common tasks include:
- Trimming empty space at the beginning of a sample so the effect plays instantly when triggered.
- Normalizing volume levels so all your effects are consistent.
- Converting files to MP3 format if necessary.
Audio and Accessibility
Not all users will appreciate or benefit from sound effects. Screen reader users, who navigate the web through audio narration, may have their experience interrupted by clashing UI sounds. It's critical to provide a mute button early in the tab order so users can disable audio without missing it. Ideally, no sound should play until the user has had a chance to interact with this control, and its state should persist across page loads.
Conversely, deaf users and those with muted devices won't be aware that sound is playing at all. Never use audio as the sole channel for important information. If a sound indicates a successful action, ensure a visual confirmation accompanies it so the site remains fully usable in silence.
Example Recipes
Interactive Checkbox
A rapid click triggers a different sound than a delayed one, adding a tactile feel to a standard form control.
jsx function Checkbox() { const [playOn] = useSound('/sounds/checkbox-on.mp3'); const [playOff] = useSound('/sounds/checkbox-off.mp3'); return ( (e.target.checked ? playOn() : playOff())} /> ); }Interrupting Sounds
Sometimes a sound should only play while the user interacts with an element. This example continuously replays an effect while hovering, but it stops immediately when the mouse leaves the area.
jsx function HoverSound() { const [play, { stop }] = useSound('/sounds/hover.mp3'); return (Rising Pitch
You can add delight with a small amount of logic. In a "Like" button component, increment a counter on each click and pass it to the hook to raise the pitch of the sound each time it plays.
jsx function LikeButton() { const [count, setCount] = React.useState(0); const [play] = useSound('/sounds/like.mp3', { playbackrate: 1 + count * 0.1, }); return ( ); }Play/Pause Control
The same principle applies to media controls. A button can toggle between distinct play and pause sounds, creating a more polished media playback experience.
Audio Sprites and Drum Machines
Components with many sounds may benefit from audio sprites—a single audio file containing several distinct effects. This reduces the number of HTTP requests and simplifies file management. A drum machine demo uses a sprite to trigger different percussion sounds with both button clicks and keyboard shortcuts (1–4), with the keyboard controls requiring a click on the interface first to focus the iframe.
Exploring the Possibilities
Audio on the web remains an under-explored area. While sound design won't suit every project, this hook provides an accessible way to experiment with the right kind of project. There's substantial room for creativity, and starting with a single, well-placed sound effect is a low-risk way to enhance the user experience. For further implementation details, check out the documentation available on the hook's GitHub repository.



