Guide
Choosing Between ChromeHeadless and Chrome Launchers in Karma for CI and Local Development
Guide to choosing ChromeHeadless versus Chrome launchers in Karma, with a config example that switches based on CI environment.
Published by Tasadduq Burney
20 Nov 2025, 03:51 UTC
3 min64.8K views0

Decision Overview
The decision is which browser launcher to configure in Karma’s karma.conf.js file: the headless variant (ChromeHeadless) for automated pipelines or the headed variant (Chrome) for local development where visual debugging is useful.
Constraints
- Continuous Integration (CI) environments often lack a graphical display and require the test process to exit after a single run.
- Local developers benefit from seeing the browser window to inspect DOM failures, CSS issues, or to pause execution with breakpoints.
- The host operating system must have the corresponding Chrome/Chromium binary available in
$PATHor explicitly pointed to via a custom launcher. - Memory‑constrained CI runners may suffer if multiple browser instances are launched concurrently.
Option Comparison
| Option | Typical Use Case | GUI Required? | Single‑Run Default | Memory Footprint |
|---|---|---|---|---|
ChromeHeadless | CI pipelines, automated testing | No | Yes (via singleRun: true) | Lower (no GPU/rendering overhead) |
Chrome | Local development, debugging | Yes | No (watch mode) | Higher (full browser UI) |
Trade‑offs
- Visibility: Headless mode can hide layout‑driven or CSS‑only bugs that are apparent in headed mode.
- Setup Complexity: Headless launchers may need extra flags (e.g., disabling GPU, sandbox) on certain CI images.
- Resource Usage: Running multiple headed browsers in parallel on a CI node can exhaust RAM; headless reduces this risk.
- Feedback Loop: Local developers get immediate visual feedback, speeding up test‑driven debugging.
Concrete Implementation
The following karma.conf.js selects the launcher based on the environment variable CI. When CI=true (common in CI services), it uses a headless launcher with conservative flags; otherwise it falls back to the headed Chrome launcher and enables watch mode.
// karma.conf.js
module.exports = function (config) {
const isCI = process.env.CI === 'true';
let browsers = [];
let singleRun = false;
if (isCI) {
// Use a custom headless launcher to avoid GPU issues on some CI images
browsers = ['ChromeHeadlessCI'];
singleRun = true;
} else {
// Local development: headed Chrome with watch mode
browsers = ['Chrome'];
singleRun = false;
}
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'src/**/*.js',
'test/**/*.spec.js'
],
preprocessors: {
'src/**/*.js': ['babel']
},
browsers: browsers,
singleRun: singleRun,
customLaunchers: {
ChromeHeadlessCI: {
base: 'ChromeHeadless',
flags: [
'--no-sandbox',
'--disable-gpu',
'--disable-dev-shm-usage',
'--window-size=1280,1024'
]
}
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: !singleRun,
});
};
Validation Steps
- Set the environment variable and start Karma:
- For CI simulation:
CI=true karma start - For local dev:
CI= karma start(or unsetCI) - Observe the output:
- In CI mode the process should exit after the test run, returning a non‑zero code on failure.
- In local mode Karma stays alive, watches files, and opens a Chrome window.
- Inspect the launched browser:
- Run
ps aux | grep Chrometo verify whether a headed or headless process is present. - Check that the headless launcher includes the flags defined in
customLaunchers(visible in the full command line). - Optional: Introduce a known CSS‑only failure (e.g., a missing width) and confirm that it is reported in headed mode but may be missed in headless mode, illustrating the trade‑off.
Limitations and Practical Checks
- The headless launcher assumes Chrome/Chromium is installed; if not, Karma will fail with "Cannot find binary". Verify with
google-chrome --versionorchromium-browser --versionbefore running tests. - Running many parallel headless instances can still consume memory; monitor CI node usage and consider limiting concurrency via
concurrencyin Karma if needed. - Some CI images require additional flags (e.g.,
--disable-setuid-sandbox) – adjust theflagsarray incustomLaunchersas necessary.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.