Mute All Except Background Music in Howler.js

This article explains how to implement a “mute all except background music” feature in Howler.js. You will learn how to categorize your audio assets, track active sound instances, and apply targeted muting to mute sound effects while keeping your background music playing.

The Challenge with Howler.js Global Muting

Howler.js provides a convenient global mute function: Howler.mute(true). However, this function mutes every single sound managed by the library, including your background music (BGM). To mute only specific types of audio, such as sound effects (SFX), while keeping the music playing, you must manage your sound groups manually.

Method 1: Using Custom Tags on Howl Instances

The cleanest way to implement this feature is by adding a custom property to your background music Howl instance. You can then iterate through all active howls using the global Howler._howls array and mute everything that is not tagged as background music.

Step 1: Initialize Your Sounds

When creating your Howl instances, tag your background music with a custom property, such as isBGM: true.

// Background Music
const backgroundMusic = new Howl({
  src: ['audio/bgm.mp3'],
  loop: true,
  volume: 0.5
});

// Attach a custom flag
backgroundMusic.isBGM = true;

// Sound Effects
const clickSound = new Howl({ src: ['audio/click.mp3'] });
const explosionSound = new Howl({ src: ['audio/explosion.mp3'] });

Step 2: Implement the Mute Function

Use the internal Howler._howls array to loop through all active audio instances and toggle their mute status based on the custom flag.

let sfxMuted = false;

function toggleMuteAllExceptBGM() {
  sfxMuted = !sfxMuted;

  // Iterate through all active Howl instances
  Howler._howls.forEach(howl => {
    if (!howl.isBGM) {
      howl.mute(sfxMuted);
    }
  });
}

Method 2: Managing SFX in an Array

If you prefer not to rely on Howler’s internal _howls array, you can maintain your own reference array for sound effects and loop through them when muting.

Step 1: Group Your Sounds

Create an array to store all of your non-music audio instances.

// Background Music
const bgm = new Howl({
  src: ['audio/bgm.mp3'],
  loop: true
});

// Sound Effects Array
const sfxGroup = [
  new Howl({ src: ['audio/jump.mp3'] }),
  new Howl({ src: ['audio/win.mp3'] }),
  new Howl({ src: ['audio/lose.mp3'] })
];

Step 2: Create the Toggle Function

Loop through your custom array to apply the mute state.

let sfxMuted = false;

function muteSFXOnly() {
  sfxMuted = !sfxMuted;
  
  sfxGroup.forEach(sound => {
    sound.mute(sfxMuted);
  });
}

This method is highly predictable and avoids accessing undocumented properties of the Howler library.