Extension config (extension.config.js)
Use one config file to set browser defaults, command behavior, and bundler customization.
Share browser defaults, command options, and build settings across your team without repeating CLI flags. Extension.js reads extension.config.js (or .mjs / .cjs) from your project root and applies it to dev, start, preview, build, and bundler config.
How it works
Add extension.config.js at your project root (same level as package.json in typical setups).
Supported file names:
extension.config.jsextension.config.mjsextension.config.cjs
Top-level keys:
Environment loading for config files
extension.config.* runs in Node and should read values from process.env.*.
- Extension.js preloads env files before evaluating
extension.config.*. - It first checks the project directory.
- In monorepos, if no project-local
.env*file is found, it falls back to the nearest workspace root (directory containingpnpm-workspace.yaml) and applies the same order there. - Prefer built-in env preload over importing
dotenvin your config file.
Browser configuration
Need different browser defaults per target? Use browser:
Supported browser keys include: chrome, edge, firefox, chromium, chromium-based, gecko-based.
Common browser fields:
profile,persistProfilepreferencesbrowserFlags,excludeBrowserFlagschromiumBinary,geckoBinaryextensions(companion load-only extensions)
Browser target capabilities
Commands configuration
Use commands to define defaults per command:
Notes:
- Top-level
extensionsandtranspilePackagesare merged into command defaults. - Per-command values override top-level values.
startis supported the same way asdev/preview/build.
Command capabilities (shared)
build command capabilities
dev command capabilities
Logging capabilities
Webpack configuration
Need advanced bundler customization? Use config to patch the generated config:
config may also be an object, which is merged on top of the generated config.
Full sample
Best practices
- Keep browser-specific values in
browser: Keep command definitions focused on workflow, not browser internals. - Use top-level defaults intentionally: Put shared
extensions/transpilePackagesat root; override only where needed. - Prefer
chromiumBinary/geckoBinarynames: They align with current command and type surface. - Keep
confighook minimal: Add only what cannot be expressed through first-class Extension.js options.
Next steps
- Learn more about Browsers Available.
- Learn more about Rspack Configuration.
