dist/<browser>. It can also generate zip packages for distribution.
How it works
Run a production build:chromium unless you override it.
Browser selection
You can target a specific browser/engine:chromeedgefirefoxchromiumchromium-basedgecko-based/firefox-based(aliases)
chrome, edge, and firefox.
Output layout
Each target writes to its own folder:dist/chromedist/edgedist/firefoxdist/chromiumdist/chromium-baseddist/gecko-based
dev launches a different Chromium-family binary as a fallback. See Requested target vs. launch binary.
Build capabilities
Generating a zip file
Generate a distribution zip from each target output with--zip:
name + version + browser, for example:
dist/my-extension-1.0.0-chrome.zip
dist/my-release-chrome.zip, beside the dist/<browser> folder rather than inside it. The browser is always appended, so each target keeps its own archive even when two builds share one name.
Include source archive
Use--zip-source to generate a source archive alongside distribution output.
--zip-source produces:
dist/<name>-<version>-source.zip, ordist/<your-name>-source.zipwhen you pass--zip-filename. The source is the same for every browser, so one build writes one source archive and its name carries no browser.
Firefox store readiness: data collection permissions
Since November 2025, addons.mozilla.org rejects every new add-on whose manifest lacksbrowser_specific_settings.gecko.data_collection_permissions, and Mozilla has announced the key becomes mandatory for all extensions during 2026. Extensions that transmit no data must still declare it explicitly:
extension create include this declaration, and the firefox: prefix keeps it out of Chromium builds. A production Firefox build warns when the resolved manifest lacks the key, so a missing declaration surfaces at build time instead of at submission review.
Declaring "none" when the extension does transmit user data is an AMO policy violation. If your extension collects or transmits anything, declare the matching categories instead. See Mozilla’s built-in data consent documentation for the category list. Firefox parses the key from version 140 on desktop (142 on Android) and it is safe on both Manifest V2 and V3.
Polyfilling browser APIs
If your code relies on Gecko-stylebrowser.* APIs and you need Chromium compatibility, enable --polyfill:
Best practices
- Build per target in continuous integration (CI): Treat each browser output as an independent artifact.
- Use a browser matrix command for parity checks: Catch target-specific issues early in one pipeline step.
- Package intentionally: Use
--zipfor store uploads and--zip-sourcefor traceable source artifacts. - Keep target configuration explicit: Use
extension.config.*command/browser defaults for reproducible builds.
Next steps
- Learn more about the Browsers available.
- Explore Path resolution for asset/output mapping details.

