Use one extension codebase across browsers and environments without hardcoding values.
Manage API hosts, keys, and browser-specific values cleanly across environments. Extension.js resolves env files during compilation, injects public variables into JavaScript (process.env and import.meta.env), and replaces placeholders in emitted .json and .html assets.
Extension.js checks environment files in priority order and uses the first matching file:
.env.[browser].[mode]: Browser-specific environment variables for a specific mode..env.[browser]: Browser-specific environment variables..env.[mode]: Mode-specific environment variables..env.local: Local-only overrides..env: Default environment variables..env.example: Fallback when no env file above exists.In addition, .env.defaults is loaded as default values, and system environment variables (process.env) take final precedence.
Note: File selection is single-file priority (plus
.env.defaults+ system env), not full cascading across all files.
Extension.js injects built-in variables at compile time, so browser and mode are always available in your extension code.
| Variable Name | Description |
|---|---|
EXTENSION_PUBLIC_BROWSER |
The current browser target for your extension (e.g., chrome, firefox, edge). |
EXTENSION_PUBLIC_MODE |
The mode in which your extension is running, such as development or production. |
EXTENSION_BROWSER |
Browser target (non-legacy alias). |
EXTENSION_MODE |
Build mode (non-legacy alias). |
BROWSER |
Short browser alias. |
MODE |
Short mode alias. |
NODE_ENV |
Node environment aligned to compiler mode (development / production). |
All built-ins above are available through both process.env.* and import.meta.env.*.
| Variable pattern | Purpose | Available in JS runtime | Notes |
|---|---|---|---|
EXTENSION_PUBLIC_* |
Expose user-defined values to extension code | Yes (process.env + import.meta.env) |
Safe-to-ship values only |
| Variable pattern | Purpose | Available in JS runtime | Notes |
|---|---|---|---|
$EXTENSION_* tokens in emitted .html / .json |
Build-time placeholder replacement in static assets | Not as JS vars | Avoid using secrets in static templates |
| Variable | Type | Notes |
|---|---|---|
EXTENSION_PUBLIC_BROWSER |
built-in | Browser target |
EXTENSION_PUBLIC_MODE |
built-in | Build mode |
EXTENSION_BROWSER |
built-in alias | Browser target |
EXTENSION_MODE |
built-in alias | Build mode |
BROWSER |
built-in alias | Short browser name |
MODE |
built-in alias | Short mode name |
NODE_ENV |
built-in | Compiler mode |
| Variable | Purpose | Typical usage |
|---|---|---|
EXTENSION_AUTO_EXIT_MS |
Auto-exit dev process after N ms | CI hard-stop control |
EXTENSION_FORCE_KILL_MS |
Force-kill timeout fallback | CI cleanup resilience |
EXTENSION_VERBOSE |
Verbose diagnostics in selected flows | Debugging CLI behavior |
EXTENSION_AUTHOR_MODE |
Maintainer/author diagnostics mode | Internal diagnostics and tooling |
Need different values per browser? Extension.js supports browser-scoped env files such as .env.chrome and .env.firefox. You can also combine browser and mode for a single build variant:
.env.chrome.development: Applied only when running the extension in Chrome during development mode..env.firefox.production: Applied only when building the extension for Firefox in production mode.Priority order is:
.env.[browser].[mode].env.[browser].env.[mode].env.local.env.env.exampleYou can define custom variables in env files at project root.
Only variables prefixed with EXTENSION_PUBLIC_ are injected into JavaScript bundles (process.env / import.meta.env).
Important: Variables without EXTENSION_PUBLIC_ are not injected into JS bundles.
However, placeholders in emitted .json/.html files can resolve $EXTENSION_* tokens, so avoid referencing secrets in static asset templates.
You can use environment variables in manifest.json, locales, HTML, and JavaScript/TypeScript files.
manifest.jsonmanifest.json does not natively support environment variables, but Extension.js replaces supported placeholders during build. For example:
During compilation, $EXTENSION_PUBLIC_API_KEY is replaced with the resolved env value.
You can also use placeholders in locale files when values should change by environment. For example:
When assets are emitted, placeholders such as $EXTENSION_PUBLIC_SITE_URL are replaced with resolved values.
You can also use placeholders in static HTML files (for example, under pages/):
When built, $EXTENSION_PUBLIC_API_KEY is replaced in the output HTML.
In React/JSX/TS files, read env values with process.env:
These values are inlined at compile time and can vary by browser/mode.
import.meta supportFor ESM workflows, Extension.js also supports import.meta.env:
import.meta.env and process.env have parity for injected env keys.
EXTENSION_PUBLIC_..env.defaults for shared defaults: Keep predictable team defaults while allowing local/system overrides.$EXTENSION_* tokens in HTML/JSON templates..env.example and ignore real env files (.env, .env.local, browser/mode variants).extension.config.js.