start when you want a production build and immediate browser launch in one command.
The start command runs a production build first, then launches the built extension using the same flow as the preview command.
When to use start
- Manually validating production behavior right after compilation.
- Reproducing runtime differences between watch mode and production output.
- Running a production-like check locally without a separate
buildthenpreviewstep.
Start command capabilities
How it differs from other commands
dev: dev server + hot module replacement (HMR)/watch modebuild: production build onlypreview: launch an existing built extension without buildingstart:build+previewin sequence
Usage
Arguments and flags
Two deprecated aliases are hidden from
--help but still work:
--wait-format <pretty|json>maps onto--outputand warns once on stderr. Migrate scripts to--output.--authorand--author-modemap onto--debug.
Browser support
start has no Safari path. Passing --browser safari (or webkit-based) exits with E_COMMAND_UNSUPPORTED_FOR_TARGET. The reason is measured. Safari’s WebDriver route does load an unpacked folder, and the background even runs, but Safari grants the extension zero host origins. Content scripts never inject, and no API call can grant the access afterwards. Use dev or build for Safari targets.
Automation metadata
start writes readiness metadata to:
dist/extension-js/<browser>/ready.json
--no-browser:
- Wait for
status: "ready"before launching external runners. - Handle
status: "error"as a deterministic failure signal. - Use
runIdandstartedAtto correlate a specific runtime session.
Stop the browser from launching
Two flags sound alike and do different things:--no-browser also has a config form, commands.start.noBrowser: true, and an environment form, EXTENSION_CLI_NO_BROWSER=1. dev, start, and preview all accept both flags.
--no-browser and readiness synchronization
--no-browser only disables browser launch. It does not block external runners until the production build finishes.
For production-oriented Playwright, continuous integration (CI), and AI workflows:
- Run
extension start --no-browseras the producer process. - Run
extension start --wait --browser=<browser>as the readiness gate. - Launch external browser automation only after
status: "ready".
--wait exits non-zero on error/timeout and ignores stale contracts from dead processes (pid no longer alive).
Because start can finish quickly, a contract from a completed run still counts when its timestamp is within a 60 second window.
--wait requires a local project path. Passing a remote URL exits with E_ARGS.
Passing both --wait and --no-browser in the same invocation exits with E_INVALID_OPTION, because --wait only reads a contract that another process writes. Run them as two processes, as in the steps above.
Machine output with --output json
--output json prints schema-1 envelopes on stdout, one JSON object per line:
- A plain
startrun prints onestatus: "started"frame once the build finished and the browser launched. It carries the project path, browser list,pid, andport: null, because a run-only session binds no port. A run that fails prints only its failure frame, never astartedframe before it. - A
start --waitrun prints onestatus: "ready"frame on success. Itsvalue.resultsarray carries the full ready contract per browser. - A
start --waitrun that reads a contract inerrorstatus prints oneok: falseframe that names the cause, for exampleE_BROWSER_LAUNCHwhen the browser never started orE_BROWSER_EXITEDwhen it exited. See the ready.json contract for the full list. - A failed build prints one
ok: falseframe withstatus: "build-failed"before the process exits1. A compile error carrieserror.code: "E_COMPILE". A missing project folder carriesE_PROJECT_NOT_FOUND, a folder with no manifest carriesE_MANIFEST_NOT_FOUND, and a manifest that does not parse carriesE_MANIFEST_INVALID. A config file that fails to load carriesE_CONFIG_LOAD, and a remote URL that gives no usable archive carriesE_REMOTE_ZIP_INVALID,E_REMOTE_FETCH_TIMEOUT, orE_REMOTE_DOWNLOAD. - A bad
--chromium-binaryor--gecko-binarypin prints oneok: falseframe withstatus: "usage"anderror.code: "E_BROWSER_BINARY_INVALID". That covers a path that does not exist, a file that is not executable, and a binary that does not answer its version probe within 10 seconds. The command ends and leaves nothing running. - A browser that cannot start prints one
ok: falseframe withstatus: "failed". The code isE_BROWSER_LAUNCHwhen the binary is executable but the system cannot start it or Firefox exits before its debugger answers, andE_BROWSER_CONNECTwhen Firefox runs but its debugger never answers.
Logging flags
These flags are experimental and may change between minor releases.Shared global options
Also supports Global flags.Examples
Start with default browser
Start in Firefox
Build and skip browser launch
Behavior notes
startdoes not run a dev server and does not provide hot module replacement (HMR) or watch mode.startis production-mode oriented. Usedevfor iterative local development.- For machine consumers, parse
dist/extension-js/<browser>/ready.jsoninstead of terminal text.

