Dev command
Use dev for day-to-day browser extension development with watch mode, browser launch, and context-aware update behavior.
dev runs the development pipeline, watches project files, and applies update strategies based on what changed (HMR, hard reload, or restart-required diagnostics).
When to use dev
- Building features and validating changes in real time.
- Debugging extension behavior in one or more browser targets.
- Running source-inspection workflows with
--source.
Use build for production artifacts, start for production build + launch, and preview to run existing build output only.
If your extension lives inside a monorepo/submodule, review how extension.config.* loads env files (including workspace-root fallback): Environment variables.
What dev gives you
Usage
If no path is provided, Extension.js uses process.cwd().
Core options
Automation metadata (recommended for scripts/agents)
When dev runs, Extension.js emits machine-readable metadata under:
dist/extension-js/<browser>/ready.jsondist/extension-js/<browser>/events.ndjson
For automation (Playwright, CI, AI agents), prefer these files over terminal log parsing.
ready.json should be treated as the readiness contract:
status: "starting"while bootingstatus: "ready"when runtime is readystatus: "error"for startup/compile failuresrunIduniquely identifies a runtime sessionstartedAtmarks the runtime session start timestamp
--no-browser and readiness synchronization
--no-browser only disables browser launch. It does not block external runners until compile is usable.
For Playwright/CI/AI workflows:
- run
extension dev --no-browseras a long-lived process - run
extension dev --wait --browser=<browser>as the readiness gate - launch external browser automation only after
status: "ready"
--wait is designed for a second process (or CI step) and exits non-zero on error/timeout.
When --wait sees a stale ready.json from a dead process (pid no longer alive), it keeps waiting for a live producer.
If both --wait and --no-browser are passed to the same command invocation, --wait takes precedence and the command runs in wait-only mode.
Source inspection workflow
Use source options only with dev:
--source <url>to run from a remote extension source--watch-source/--no-watch-sourceto control remote polling behavior
start and preview do not support source-inspection flags.
Source flags
Logging flags
Shared global options
Also supports global flags.
Examples
Running a local extension
Running a remote extension
Running in Firefox
Running in multiple browsers in sequence
Running in brave as a custom binary
Best practices
- Browser compatibility: Test your extension in different browsers to ensure compatibility with the target audience.
- Polyfilling: If Firefox or a Gecko-based browser is also a target, use the
--polyfillflag to enable compatibility for thebrowser.*API in Chromium-based browsers. - Source inspection workflows: Use
dev(notstart/preview) when you need source inspection options. - Automation reliability: Treat
devas the watch-mode "dev friend" (--no-browser+dev --wait) andstartas the production "test friend" (--no-browser+start --wait) for Playwright/CI flows (--wait-format=jsonfor machine consumers).
Next steps
- Build production artifacts with
build. - Validate production launch flow with
start. - Review browser targeting with browser-specific manifest fields.
- Configure shared defaults in
extension.config.js. - Review config env loading behavior in Environment variables.
