Sound manager for the web · TypeScript · Web Audio API

All your app's audio, on one mixing desk.

soundhub loads each sound once and keeps track of it for you. Play, fade, group, sprite, stream and place sounds in 3D, and follow every change on one typed event bus.

Download v6.5.1 Try the demos
npm install soundhub
  • 23 KB gzipped
  • 0 dependencies
  • MIT licence
  • TS + JS
Console idle
−∞ Rain
−∞ Birds
−∞ Brook
−∞ Crickets
80%
C
waiting for the first eventbus

Four nature recordings from the demos, loaded and played by the real soundhub. Drag a strip to set its volume with setSoundVolume(). The waves behind this panel read the hub's master output.

Bundle23 KB
Typed events40
Dependencies0
Downloads since 20248,000+

Works with

No adapter needed. Each guide comes with an example you can open in StackBlitz.

What it does

The basics you expect, plus the bookkeeping you would write yourself.

One event bus

40 typed events on one bus, filtered per sound or per overlapping instance.

hub.addEventListener(ENDED, next, { soundId: 'music' })

Overlap with a voice limit

Every shot gets its own instance. A full group stops its oldest voice instead of piling up.

hub.createSoundGroup('lasers', { maxInstances: 8 })

Sprites

One file, many sounds, each cut into its own buffer so it starts on the exact sample.

hub.playSprite('ui', 'click')

3D sound and a moving listener

Place sounds around the ear, or move the ear through the scene for a first-person camera.

hub.setListenerPosition(player.x, 0, player.z)

Streams for long files

An hour of audio plays without decoding it first, and still runs through the panner and the limiter.

await hub.loadStream('episode', url)

Lock screen and limiter

Artwork and media keys on the lock screen, and a limiter so many sounds at once cannot clip.

hub.setMediaSession('episode', { title })

Start in a minute

Coming from Howler.js?

Change one import and your Howl code runs on soundhub. From there you can use what Howler does not have: music that ducks under a voice, footsteps that vary, interface sounds without files, and a hub that knows the state of every sound.

// was: import { Howl, Howler } from 'howler';
import { Howl, Howler } from 'soundhub/howler';

// The Howler code you have keeps running
const music = new Howl({ src: ['theme.mp3'], loop: true });
const voice = new Howl({ src: ['line.mp3'] });
music.play();

// What Howler cannot do is on Howler.hub
Howler.hub.duck(music.soundhubId, {
  when: voice.soundhubId,
  amount: 0.3,
});
voice.play();   // the music steps back
soundhub compared with Howler.js 2.2.4
FeaturesoundhubHowler.js 2.2.4
EventsOne typed bus, 40 types, a filter per listenerCallbacks per Howl
ProgressFull state on the eventPoll seek() yourself
Long filesloadStream, still in the Web Audio graphhtml5: true, outside it
3D on long filesYesNo, HTML5 mode skips the panner
Voice limitsGroups with maxInstancesNo cap on concurrent instances
LimitermasterLimiter: trueBuild it on Howler.ctx
Duckingduck('music', { when: 'voice' })Fade by hand in onplay and onend
VariationscreateVariations, with a pitch and volume spreadPick a random sprite yourself
Sounds without filessoundhub/ui, and addBuffer for your ownEvery sound needs a url

Where it comes from

Built by someone who has been doing this since Flash.

My first sound engine was in ActionScript 3.0. This one went on npm in December 2024 as sound-manager-ts, and became soundhub in August 2026 with the same code under a new name.

  1. Flash eraA sound engine in ActionScript 3.0
  2. 19 Dec 2024sound-manager-ts 1.0.0 on npm
  3. 2025 to 2026More than fifty releases, over 8,000 downloads
  4. 29 Aug 2026Renamed to soundhub, version 6.0.0

Questions about using a sound manager

What is a sound manager for the web?

A sound manager is the layer between your code and the browser audio system. It loads audio files once, keeps track of every sound that is playing, and gives you one place to start, stop, fade, pan or position them. Without one you end up writing that bookkeeping yourself in every project.

Can I use soundhub.js as a sound engine for a browser game?

Yes. Each play call can create its own instance, so overlapping shots and explosions do not cut each other off, and sound groups let you cap how many instances a category may hold at once. Sound sprites keep dozens of short effects in a single file, which is the usual approach for web games.

How is it different from using the HTML audio element?

The audio element plays one file at a time and gives you no control over panning, spatial position or grouping. soundhub.js runs on the Web Audio API, so the same sound can play many times at once, each with its own volume, pan and 3D position.

Does the sound player work on mobile browsers?

Yes. Mobile browsers keep audio suspended until the user interacts with the page, and the library resumes the audio context on that first gesture. It also mutes when the tab goes to the background and resumes on focus, which is what mobile users expect.

Is soundhub.js an alternative to Howler.js?

Yes. Change the import to soundhub/howler and existing Howl code runs on soundhub. Beyond what Howler does, soundhub ducks music under a voice, gives one name to several takes of a sound, ships interface sounds that need no files, keeps the state of every sound on one typed event bus, caps voices with sound groups, and keeps long streamed files inside the Web Audio graph, so 3D panning still works on them.

How large is the library and does it have dependencies?

It is around 23 KB gzipped and has zero runtime dependencies. It ships as an ES module, a CommonJS build and a UMD build, with types for every TypeScript setup.