Cross-browser compatibility
Extension.js handles browser-specific setup during development and build, so the same project can produce runtime-correct outputs across Chromium and Gecko targets.
Use one manifest.json, target specific browsers or custom binaries, and enable polyfills when needed for browser.* API compatibility in Chromium-family targets.
How it works
1) Select a browser target
Choose where you want to run your extension.
Use --browser for common targets, or pass a custom browser binary.
Use a binary path that matches your OS:
- macOS:
/Applications/Brave Browser.app/Contents/MacOS/Brave Browser - Linux:
/usr/bin/brave-browser(or another Chromium-based browser binary) - Windows:
"C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
When you pass a binary, Extension.js maps it to a browser engine target:
chromium-basedfor--chromium-binarygecko-basedfor--gecko-binary
2) Compile with browser-specific manifest filtering
During compilation, only manifest fields for the selected browser are included.
For example:
For Chromium-family targets, Extension.js uses prefixes like chromium:, chrome:, and edge:.
For Firefox-family targets, Extension.js uses firefox: and gecko:.
Note: Browser-prefixed manifest fields are covered in detail in Browser-Specific Manifest Fields.
3) Output per browser target
Each target is written to its own build folder:
dist/chromedist/edgedist/firefoxdist/chromium-based(custom Chromium engines)dist/gecko-based(custom Gecko engines)
This keeps builds organized and easier to ship in CI.
4) Optional browser.* polyfill for Chromium targets
If your code uses browser.*, enable --polyfill for Chromium-family targets:
When enabled, Extension.js uses webextension-polyfill for non-Firefox targets.
For Firefox, this step is skipped because browser.* is already built in.
Best practices
- Keep one codebase: Put browser differences in prefixed manifest fields when possible.
- Build one target at a time: Generate dedicated artifacts (
dist/<browser>) for each browser in CI. - Use
--polyfillwhen needed: Enable it only when your code depends onbrowser.*in Chromium-family targets. - Check API support early: Use MDN WebExtensions docs before relying on browser-specific APIs.
Next steps
- Learn more about the Browsers Available.
- Learn more about Browser-Specific Manifest Fields.
