Skip to main content
Use one configuration file to set browser defaults, command behavior, and bundler customization. Share browser defaults, command options, and build settings across your team. Stop repeating CLI flags. Extension.js reads extension.config.js (or .mjs / .cjs) from your project root. It applies settings to every command and the bundler.

How it works

Add extension.config.js at your project root (same level as package.json in typical setups). Supported file names:
  • extension.config.js
  • extension.config.mjs
  • extension.config.cjs
Top-level keys:

Type-safe configuration

Extension.js exports the FileConfig type from the extension package so editors can autocomplete and type-check your config. Annotate the export with a JSDoc @type tag — it works in extension.config.js, .mjs, and .cjs without a build step:

Environment loading for configuration 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 folder.
  • In monorepos, if Extension.js finds no project-local .env* file, it falls back to the nearest workspace root. The workspace root is the folder containing pnpm-workspace.yaml.
  • Prefer built-in env preload over importing dotenv in your configuration file.

Browser configuration

Need different browser defaults per target? Use browser:
Supported browser keys include: chrome, edge, firefox, chromium, chromium-based, gecko-based, firefox-based. Common browser fields:
  • profile, persistProfile
  • preferences
  • browserFlags, excludeBrowserFlags
  • chromiumBinary, geckoBinary
  • extensions (companion load-only extensions)

Browser target capabilities

Commands configuration

Use commands to define defaults per command:
Notes:
  • Extension.js merges top-level extensions and transpilePackages into command defaults.
  • Per-command values override top-level values.
  • The start command runs build then preview internally. Extension.js applies settings from commands.start, including browser-launch options like profile, browserFlags, and startingUrl. You can also put build-specific settings in commands.build.

Command capabilities (shared)

build command capabilities

dev command capabilities

Logging capabilities

Rspack configuration

Need advanced bundler customization? Use config to patch the generated Rspack configuration:
config may also be an object, which Extension.js merges 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 / transpilePackages at root; override only where needed.
  • Prefer chromiumBinary/geckoBinary names: They align with current command and type surface.
  • Keep config hook minimal: Add only what first-class Extension.js options do not cover.

Next steps