Skip to content

Karma Custom Launchers

customLaunchers is the tool you reach for whenever a built-in browser configuration needs a small tweak — extra flags, a different profile setting, or an alias with a clearer name. This lesson covers the pattern in depth.

Extending a Base Launcher

Every custom launcher configuration starts from a base — an existing launcher name provided by an installed package, like ChromeHeadless or FirefoxHeadless. You then add or override settings on top of that base, most commonly extra command-line flags.

config.set({
  customLaunchers: {
    ChromeHeadlessCI: {
      base: 'ChromeHeadless',
      flags: ['--no-sandbox', '--disable-gpu']
    }
  },
  browsers: ['ChromeHeadlessCI']
});

ChromeHeadlessCI is a name you invent yourself — it's not a Karma convention, just a descriptive label for your extended configuration.

The customLaunchers Object Shape

customLaunchers: {
  <your-chosen-name>: {
    base: '<built-in-launcher-name>',
    flags: ['--flag-one', '--flag-two'],
    // launcher-specific extras, e.g.:
    prefs: { /* Firefox only */ }
  }
}
  • base is required and must match an existing launcher name from an installed package.
  • flags is an array of command-line arguments appended when the browser process starts.
  • You can define as many custom launcher entries as you need, each with its own descriptive name.
  • Custom launchers are still referenced the normal way, by name, inside the browsers array.

Custom Launcher Recipes

Ready-to-copy custom launcher configurations for common scenarios.

Scenario Configuration
Docker/CI-safe Chrome { base: 'ChromeHeadless', flags: ['--no-sandbox', '--disable-gpu'] }
Fixed viewport size { base: 'ChromeHeadless', flags: ['--window-size=1366,768'] }
Debuggable headless instance { base: 'ChromeHeadless', flags: ['--remote-debugging-port=9222'] }
Firefox with tweaked prefs { base: 'FirefoxHeadless', prefs: { 'some.pref': false } }

Naming Custom Launchers Clearly

Since custom launcher names are entirely your own choice, using a clear, descriptive convention pays off as a config grows — especially in teams where multiple people maintain the same karma.conf.js over time.

  • Suffix with the environment or purpose: ChromeHeadlessCI, ChromeHeadlessDebug.
  • Avoid names that could be mistaken for a real built-in launcher name.
  • Document unusual flags with a brief inline comment explaining why they're needed.
  • Keep one canonical CI launcher per browser family rather than several near-duplicates.

Combining Multiple Custom Launchers

A single config can define several custom launchers and run them together, which is a common way to run a consistent, container-safe cross-browser suite in CI.

customLaunchers: {
  ChromeHeadlessCI: {
    base: 'ChromeHeadless',
    flags: ['--no-sandbox', '--disable-gpu']
  },
  FirefoxHeadlessCI: {
    base: 'FirefoxHeadless',
    flags: ['-headless']
  }
},
browsers: ['ChromeHeadlessCI', 'FirefoxHeadlessCI']

Common Mistakes

  • Forgetting the required base key, which causes Karma to fail resolving the custom launcher entirely.
  • Duplicating nearly identical custom launchers instead of consolidating them into one well-named configuration.
  • Naming a custom launcher identically (or confusingly close) to a real built-in launcher name.
  • Adding flags without documenting why, leaving future maintainers unsure which ones are still necessary.

Key Takeaways

  • customLaunchers extends a built-in base launcher with extra flags or settings.
  • Custom launcher names are arbitrary and should be chosen for clarity, not convention compliance.
  • Multiple custom launchers can be combined to run a consistent cross-browser CI suite.
  • Documenting why specific flags were added saves future debugging time for the whole team.

Pro Tip

Treat every flag added to a custom launcher as something that needs a one-line justification comment. Six months later, nobody remembers why --disable-gpu was added, and removing it blindly risks reintroducing a bug that took real effort to fix.