build compiles your extension in production mode and writes output to dist/<browser>.
For monorepo/submodule projects, see Environment variables for configuration-time env resolution (project root first, then workspace-root fallback).
When to use build
- Preparing extension packages for Chrome Web Store, Edge Add-ons, or Firefox Add-ons.
- Running continuous integration (CI) jobs that produce repeatable production artifacts.
- Validating production bundle output and browser-target differences before submission.
Build command capabilities
Usage
Build output
After runningbuild, Extension.js generates optimized files for the selected browser targets. Output goes to dist/ with one subfolder per target. Each folder contains bundled JavaScript, CSS, HTML, and required runtime assets.
For TypeScript projects,
build also regenerates the extension-env.d.ts
ambient type declarations (the same file dev writes),
so a CI tsc --noEmit stays clean whether or not you ran dev first.
JavaScript-only projects skip this step.Browser target matrix
What engine targets mean for build
build never launches a browser, so engine targets donβt point at a binary here, but they still produce a distinct artifact, not a renamed copy of a named-target build:
- Own output folder.
--browser=chromium-basedwrites todist/chromium-based, the same folderdev,preview, andstartuse for that target, so a project developed against a custom Chromium binary builds to matching paths. - Own env resolution.
.env.chromium-basedand.env.chromium-based.productionwin over the familyβs.env.chromium/.env.chrome/.env.edge, and bundled code seesEXTENSION_BROWSER === "chromium-based", so code and config can branch on βgeneric Chromiumβ vs a specific store build. - Own manifest prefix.
chromium-based:keys inmanifest.jsonresolve as the most-specific match for this target, on top of the family-widechrome:/chromium:/edge:keys.
gecko-based works the same way relative to firefox. No browser binary is required, and --chromium-binary/--gecko-binary only matter for commands that launch a browser.
Arguments and flags
--author and --author-mode are hidden, deprecated aliases for --debug.
Safari flags
These flags apply tosafari and webkit-based targets only. Passing any of them with another target exits with an error, so a typo never no-ops silently.
Safari packaging runs a preflight before the build. On a non-macOS host,
build warns and skips the Safari packaging step but still compiles the bundle. On macOS with a broken or missing Xcode, the failure is fatal.
Shared global options
Also supports Global flags.Mode override
--mode overrides the bundler mode and NODE_ENV for the build. Accepts development, production, or none. Use it to mirror Vite/webpack workflows where you need a non-production bundle for staging or debugging.
production.
Zip behavior
Examples
Building with zip output and custom filename
my-extension.zip.
Building with polyfill support
Building source and artifact zip
What a successful build prints
After the asset summary, a successful build prints two lines and stops:Build succeeded with N warning(s). in place of the first line, then the warning details.
The command prints no link and no next step. build is finished when the artifacts exist in dist/<browser>. Where they go after that is your choice, and the options are below.
Machine output with --output json
--output json prints one schema-1 envelope on stdout and routes the human build lines to stderr. Stdout stays parseable as a single JSON document.
- A successful run prints a
status: "built"frame. Itsvaluecarries the project path, built browsers, the resolved mode, and one summary per browser. Each summary records the output path, asset totals, warning text, and the Safari app identity when relevant. - A failed build prints one
ok: falseframe withstatus: "build-failed"anderror.code: "E_COMPILE"before the process exits1.
dist/extension-js/<browser>/build-summary.json. Scripts that shell out to extension build can read structured warnings there. Guard against stale files by checking the fileβs modification time.
Best practices
- Check build logs: Review logs for warnings and missing assets after each build.
- Optimize your manifest: Keep
manifest.jsoncompatible with every target browser. - Name artifacts intentionally: Use
--zip-filenamefor stable CI artifact naming. - Validate target output: Check each
dist/<browser>folder before publishing.
Next steps
- Send the build to a reviewer behind a link by following Share an unpublished build for review.
- Submit the artifacts to the browser stores by following the extension.dev publish docs.
- Get a shareable URL for a project on extension.dev with
publish. - Run existing build output with
preview. - Build and launch in one command with
start. - Configure shared defaults in
extension.config.js. - Review configuration env loading behavior in Environment variables.
- Review supported targets in Browsers available.

