CHANGELOG
Changelog
Unreleased
4.0.32 (August 8, 2026)
Features
- Expose forced env vars to template substitution too (07b7bb19)
- Inspect every modified page in the watch batch with fresh bytes (796a29da)
Fixes
- Guard the DNR override against dynamic-only manifests (380767da)
<details>
<summary>Other changes (15)</summary>
- Raise the js-yaml floor past its advisories (47ad1ea2)
- Hold react-table majors in dependabot until the v9 migration (8017287e)
- Revert the react-table 9 bump until the log-table is migrated (03601430)
- Use a comma in the legacy-path warning to pass the messaging gate (07a94549)
- Scrub the author-mode alias in the default-verbosity retry spec (6254c869)
- Drop em dashes from watch-batch comments to pass the prose gate (4f99ce00)
- Warn on stderr when logs --signals-only has no emitter to match (b8e029dc)
- True up browser-family docs and pin webkit-fork behavior (a41e54fc)
- Skip the polyfill for the webkit family (33543a39)
- Adopt the safari product block for webkit-based runs (cc55feb6)
- Print a repeated fatal-shape repair once per dev session (11873869)
- Warn on legacy manifest paths from the author source, per field (602498f5)
- Give telemetry a budget that covers a cold TLS handshake (c11f8536)
- Derive the create template list from the corpus commit it downloads (03b52829)
- Force color off in test suites, monochrome is the assertion contract (32c910b9)
</details>
4.0.30 (August 4, 2026)
<details>
<summary>Other changes (3)</summary>
- Refuse consent and identity that arrived with a git clone (a9f764dd)
- Let the MAIN world resolve assets through the bridge base (461739d7)
- Follow the examples rename to sidebar-monorepo-turborepo in the catalog (0f0f0769)
</details>
4.0.29 (August 4, 2026)
- No changes listed.
4.0.28 (August 3, 2026)
Fixes
- Guard load-checked HTML entry points in the persist gate (86feaad0)
- Harden the built-in theme contrast and per-engine key parity (05050c18)
- Fix extension-js-devtools typecheck under TypeScript 7 (56867d75)
<details>
<summary>Other changes (13)</summary>
- Drop the stale templates/wasm ignore rule (550b2589)
- Redirect guarded manifest writes to the platform null device (cc370099)
- Pin the default template corpus to a commit instead of tracking main (9f578c68)
- Convert hex theme colors for chromium builds instead of refusing (0d332d0c)
- Keep the catalog screenshot out of every scaffold and its store zip (3ac6630e)
- Make --allow-eval self-sufficient and name it in eval refusals (700c0247)
- Refuse a publish that would share a project you are not in (dc88e4df)
- Drop the template author from scaffolds instead of inheriting it (f4bd8695)
- Remove type casts left by the manifest-shape and flags campaigns (c18a55d7)
- Scope the manifest write guard per server and spare read opens (e4b7c4da)
- Compare theme_icons by value so identical manifests never diff (f4628db4)
- Declare gecko data_collection_permissions in the built-in extensions (0a7a718e)
- Print the build receipt against the merged output.path (bb9092d4)
</details>
4.0.27 (August 2, 2026)
Fixes
- Fix boring line dist classification, name fallback and warn arming (1255365a)
- Gate held share-hint strings in the extension-develop publish (26b37bc3)
<details>
<summary>Other changes (42)</summary>
- Let a stale producer re-resolve the live control port from disk (e98c1fc2)
- Capture listener events on both the chrome and browser namespaces (ef8425a0)
- Derive uninstall --all paths from installTargets instead of a literal (59065eba)
- Keep the user extension last when a companion names the same path (3ac4b071)
- Type the perfBudgets config read and add it to the public config (833e499b)
- Let unset CLI flags fall through to extension.config.js commands (47313165)
- Treat a profile of false or the string false as the system profile (e074d85d)
- Validate DNR rules per rule and fail builds with index and reason (d59a7118)
- Capture nested assets paths in the web resources fallback scans (93af863a)
- Trim the HTML asset cache key, add eviction, throw on deleted HTML (344e9a26)
- Emit the ?url rule after typed asset rules and fix custom rule checks (0bd2f578)
- Accept safari identity options in commands.dev and commands.build (9438d6ec)
- Map safari to its own devtools engine and wire the safari binary (68288701)
- Exempt webkit targets from the chrome WAR match-pattern contract (a26077c8)
- Warn when a themed manifest targets safari instead of skipping silently (9dff5c29)
- Give safari ready.json the appex id instead of a chromium hash (bc86bfc3)
- Run pnpm optional-dep installs silent to match project installs (5c3c0c04)
- Warn when a malformed package.json blanks integration detection (3f1d7369)
- Align Deno scaffolds: deno.lock strip, primary merge, deno.json wins (0f48a6ab)
- Rewrite store metadata names in one pass so extending names never double (f96580e8)
- Keep create failure cleanup away from pre-existing user content (65e7aa85)
- Clean the compiler output path instead of the context dist folder (927dac37)
- Detect the system Edge binary when the lookup exits zero (672a1be0)
- Emit one-shot builds into a staging dir and rename into dist on success (2a9b4a66)
- Merge the .extension-js ignore line into adopted project gitignores (04f6864a)
- Gitignore the env files the framework loads in new scaffolds (f352f758)
- Deny secrets in the source zip independent of any gitignore (cacff012)
- Read the stored device login as the publish token fallback (facc3db2)
- Cover per-script reinject identity for multi-script content entries (fa944653)
- Disable deno minimum dependency age in the optional deps smoke (4ce8bcf0)
- Resync the bundled javascript template to the public screenshot (3a832c9b)
- Pin waterfox-location 2.1.1 to finish the which 6 rollout (c9c4fe96)
- Bump nine location package pins to the which 6 releases (19d512d5)
- Name the requested template truthfully in the create banner and help (372cccdd)
- Drop copied template lockfiles so npm ci works in a fresh scaffold (8de42f34)
- Size the nightly e2e to a verdict and assert the CLI boots first (0fe46b4b)
- Scope the firefox e2e project to the real Firefox specs (5c476e68)
- Let the nightly e2e fail red and find the CLI it builds with (762cefc7)
- Name the browser doctor ran on and keep screenshots out of the zip (8b6d2c9b)
- Report a failed create to telemetry before the process exits (767ea493)
- Revalidate the packument so a good release stops failing (33ceb567)
- Flush telemetry before exiting so a failure is actually reported (d4ca1d63)
</details>
4.0.26 (July 31, 2026)
Fixes
- Stop a missing Discord webhook from blocking a release (e4bdd73e)
<details>
<summary>Other changes (1)</summary>
- Make init scaffold the init template instead of a different one (be5ad414)
</details>
4.0.25 (July 30, 2026)
Fixes
- Stop a stored consent from speaking for a pipeline that inherited it (4c845971)
<details>
<summary>Other changes (6)</summary>
- Update the AI help snapshot for the reworded template note (751bd442)
- Say the template rules in sentences the messaging check allows (620d4f15)
- Show every template name in create help instead of only to agents (8fba658c)
- Resync the bundled javascript template with the examples repo (3cb2d4f6)
- Give the default scaffold its own name, identity, and first commit (d3dd41f8)
- Tell the reader where to get a token when publish has none (e8cb2661)
</details>
4.0.24 (July 30, 2026)
Fixes
- Stop reporting telemetry from CI, where nobody can consent (e12fd206)
<details>
<summary>Other changes (3)</summary>
- Prove a release shipped the fix by reading the published tarball (631bced8)
- Keep reporting when CI is set but a person has a terminal (a92c9f29)
- Resync the bundled javascript template with the examples repo (9de01978)
</details>
4.0.23 (July 30, 2026)
Features
- Surface legacy manifest path warnings at scan time, not stats time (51c1b0c8)
- Surface fatal manifest repairs at patch time with one visible line (9fd5d2e5)
- Add machine-aware human sinks to the shared messaging primitives (8ba132ac)
Fixes
- Stop warning about a port conflict when port 0 asked for any port (ec1cdd33)
<details>
<summary>Other changes (11)</summary>
- Print where to share a build and name the sponsor in the README (fdd9b947)
- Name the sponsor in the README every scaffold keeps (9fd4c4d5)
- Pin npm and drop a pnpm flag that npm 12 turns into a hard error (4f05a582)
- Publish all four packages through OIDC instead of a shared npm token (9672f35e)
- Honor commands noBrowser from the file config, flag still wins (e8da1e2a)
- Stamp the user extension id on the ready contract for both families (c4f7c103)
- Warn early that a derived Safari bundle id is shared, drop Apple claim (858b2f2b)
- Warn when a second dev session targets the same browser dist (95743e52)
- Document the human sinks and the logs printer exception (4f5130f3)
- Trim snapshot and fallback notices to cause and remedy warn lines (bcb54782)
- Route browsers-bundle console output through the human sinks (e2016e21)
</details>
4.0.22 (July 29, 2026)
Fixes
- Sweep install messages and move the unpack receipt to success (c0e5c7be)
- Sweep CLI helper messages and help headings to the style spec (9e8b8114)
- Sweep the browsers-lib catalog to the terminal style spec (c7e1f5c5)
- Sweep the create catalog to error anatomy and progress voice (2770a88f)
<details>
<summary>Other changes (16)</summary>
- Extend check-messaging with word, emoji, color, and period rules (017c274a)
- Rewrite docs/MESSAGING.md as the spec v1 terminal-output standard (d1119637)
- Wrap bundler stats blocks in the standard error anatomy (eb56804d)
- Render commander parse failures through the error anatomy (b5d9e59b)
- Reword develop lib messages to spec anatomy and drop dead twins (113f4f33)
- Glyph dev-server flow lines and sweep plugin catalog copy (6eee6efe)
- Align web-extension feature catalogs with the error anatomy (158ff71e)
- Collapse the build summary into card, asset tree, and one closer (6312a294)
- Record zip artifacts on the compilation instead of printing early (6d1174c3)
- Render build errors once by skipping the raw renderer under build (ac1c42d0)
- Collapse the home dir in the fallback card Output row (55e2af24)
- Pin the dev no-browser boot transcript order with an exec spec (08c551b4)
- Give the no-browser card an Output row, one mode marker, update hint (b2333596)
- Move the resolved binary onto the card with provenance rows (fc115198)
- Unify the ready line wording and move it to the success channel (892929a8)
- Print the compile line immediately and drop successfully from it (0b55bfee)
</details>
4.0.21 (July 29, 2026)
<details>
<summary>Other changes (3)</summary>
- Report a chromium session that cannot confirm the extension loaded (7665d933)
- Print one browser row spelling across dev start preview build (f7e4f67a)
- Honor explicit zip filenames and name written zips on stdout (1293f181)
</details>
4.0.20 (July 28, 2026)
Features
- Add a capabilities command answering versions and json-capable commands (80e8e399)
<details>
<summary>Other changes (17)</summary>
- Report inspect refused targets as TargetNotFound like eval (0c11de92)
- Admit the capabilities command and theme message to contract guards (a20476c8)
- Frame every CLI exit path as one stdout envelope with structured refs (764e7521)
- Stamp profile path and browser pid, publish profile and dist helpers (9fa709af)
- Publish the whole ready contract and its type from the bridge entry (06ed3bd1)
- Mint the documented eval hint on guest-throw failures (276219f8)
- Report the resolved build mode in the JSON envelope (04b556c0)
- Name eval refusals on the wire and map unreachable targets (1ba027fc)
- Hand the WebSocket close code and reason to BridgeConsumer callers (89c128ea)
- Name open refusals on the wire so consumers stop matching prose (15544bf0)
- Record engine-loaded companion extension ids in ready.json (33d919ff)
- Reach the shipped dist contract through a package exports entry (82fed76b)
- Publish a browser-safe contracts entry with zero-import wire constants (c4807b90)
- Name the theme image in the missing theme-image build error (8f741066)
- Scope the MV2 install warning to manifests Chrome actually refuses (e5215f98)
- Fail chromium builds over theme color values Chrome refuses at load (706581d5)
- Match Chrome's message-name charset in the manifest placeholder scan (59130e63)
</details>
4.0.19 (July 28, 2026)
Fixes
- Repair CI env and platform assumptions in three spec surfaces (de3644da)
<details>
<summary>Other changes (6)</summary>
- Publish the log ranking and the control close codes (0edd8b10)
- Rename treeWithDistFilesBrowser to repair the missing separator (ce99a79e)
- Move the chromium profile path from the debug stream to the card (992fb320)
- Rename pm args and drop dead params in create message catalog (f5bd1407)
- Let a library caller package Safari and read what the build made (f116418e)
- Keep companion extensions out of the source zip (c269b83c)
</details>
4.0.18 (July 27, 2026)
<details>
<summary>Other changes (5)</summary>
- Override transitive postcss to 8.5.18 repo-wide (b525f957)
- Bump postcss to 8.5.18 for the source-map path traversal fix (826b888c)
- Hold contract bytes and drift paths steady on Windows checkouts (7cec56b2)
- Render the compile arrow with prefix() and drop its glyph exemption (b9a8717a)
- Migrate scripts harnesses from stdout tokens to the ready contract (c65b332e)
</details>
4.0.17 (July 27, 2026)
Features
- Add the schema-1 result envelope and its contract spec (1ecc5131)
- Add --debug and hide the author-mode alias behind it (b70a6598)
- Add duplicated messaging primitives with a drift spec (a476e2fd)
Fixes
- Gate the messaging standard in CI and publish it (20edc969)
- Resolve the artifact noun through one rule for every browser (8c6aa93a)
<details>
<summary>Other changes (28)</summary>
- Describe --silent truthfully and drop preview's unwired host flags (7c700cda)
- Complete the error code table and ship its golden envelopes (80e3aeab)
- Rewrite browser runner messages to the imperative standard (2ab0e17c)
- Rewrite develop core messages to the imperative standard (107d7bc4)
- Rewrite CLI helper messages to the imperative standard (7a9b9f4f)
- Rewrite web-extension feature messages to the imperative standard (fa296ccd)
- Rewrite develop leaf-plugin messages to the imperative standard (d592b69b)
- Print the card first on every path and retire the banner event (2af56bf7)
- Map the legacy format flags onto --output and free the dev failure frame (3e1d0377)
- Ship the envelope contract inside the extension-develop package (2bbb0184)
- Advertise schema-1 support in the ready contract (9366e5f4)
- Generate the help center from the command table (5e474523)
- Move internal steps to the debug channel across develop (475c4858)
- Print the card before launch work and stamp profile locks (30b9ee13)
- Emit the result envelope from every terminating command (98e85f1f)
- Stream the dev session lifecycle as schema-1 NDJSON frames (1c86f2a1)
- Seed the error code table for the remaining commands (098ac3f4)
- Emit the result envelope from build under --output json (70f786c3)
- Describe every command once, in the imperative mood (6f8bab81)
- Print the card before the ready line in no-browser mode (9f2e8733)
- Render every Extension.js card through one renderer (54c3e396)
- Point the debug docs at the flag that actually works (ca966a39)
- Drop the Author says prefix and move errors onto the glyph (14c9c8f4)
- Read the debug flag through one accessor with a closed value set (5db59b99)
- Move fmt into the shared messaging primitives (f1edd61d)
- Let commands report vendor and wait failures themselves (800aed75)
- Collect specs under the contract directory in vitest (a4d57534)
- Send first-run and update notices to stderr (ebd74c7e)
</details>
4.0.16 (July 24, 2026)
Features
- Add a package managers table and drop the README top banner (5f5bc90c)
- Add the brand banner to the README (628f0b84)
Fixes
- Resolve packed-tarball paths at run time in the CLI exec tests (abd37068)
- Correct docs: Rspack naming, Node 22, and stale links (de21465f)
<details>
<summary>Other changes (24)</summary>
- Bump CI GitHub Actions to their latest major versions (e34a5848)
- Probe exec-runner readiness in a temp dir, not the repo root (01151c5d)
- Ignore the workspace in the pnpm smoke frozen installs (bdea3770)
- Sync pnpm-lock.yaml with the extension devDependencies move (25451709)
- Stamp template provenance into scaffolds and CreateResult (75323f87)
- Accept a commit SHA or tag for the template corpus ref (709fd346)
- Strip internal tracker refs and rename client test fixture (150645a4)
- Tidy gitignore, CI perms, dependabot, and package metadata (63ccf8b4)
- Remove unused html-merge browser helper (ecb92872)
- Prune nine pnpm overrides that no longer change any resolution (74f52bbd)
- Drop the unused root extension devDep that kept postcss 8.5.10 (a4bd0c9f)
- Fall back to the framework logo when a welcome icon fails to load (bf193bb4)
- List Safari among the browsers the framework builds for (e2ad588e)
- Recover a refused dev session once the browser accepts the extension (e6d81d72)
- Report a Firefox add-on refusal and let the engine re-offer the dist (0c4314ee)
- Report Chrome refusing to load the extension instead of ready (c8fb151c)
- Isolate the browser-flags specs from an exported EXTENSION_HEADLESS (b9ab2443)
- Match the missing-JSON message to whether the build actually fails (a0e30962)
- Leave static themes uninstrumented in dev on Firefox too (54837af5)
- Honor EXTENSION_HEADLESS so automated runs never steal focus (6d80ea06)
- Refresh the messages catalog snapshot for themeImageIsEmpty (2959495a)
- Fail the build on missing theme images, warn on 0-byte ones (d206b729)
- Match the release-notes tooling to the new release commit subjects (e57964bb)
- List Safari as a supported target in the README (176736d4)
</details>
4.0.15 (July 23, 2026)
<details>
<summary>Other changes (3)</summary>
- Bump fast-uri to 3.1.4 and immutable to 5.1.9 (Dependabot) (c0647378)
- Drain stdout before exit so piped --output json frames arrive intact (3e78dada)
- Align log/event runId with ready.json and publish Firefox rdpPort (f6a639fd)
</details>
4.0.14 (July 21, 2026)
Fixes
- Guard the CLI on Node < 22.12 with a clear version error (06930647)
- Fix eval executor: surface contexts, CSP honesty, Gecko callback APIs (29a475ea)
- Stop dropping release notes and recover the lost 4.0.x changelog (1dd83616)
- Fix Firefox storage bridge and surface uncaught dev-log errors (028f939f)
<details>
<summary>Other changes (39)</summary>
- Sync bundled javascript template: STORE.md and manifest key order (d0649f41)
- Bump the js-yaml override to 4.3.0 to clear GHSA-52cp-r559-cp3m (22392bbd)
- Replace em dashes in user-facing strings to satisfy the prose gate (5581bb7b)
- Scrub source comments wave 3 of 3; annotate empty catches with Ignore (9319bcd7)
- Scrub narration and internal refs from source, wave 2 of 3 (a3f23352)
- Scrub narration and internal refs from source, wave 1 of 3 (935e71d4)
- Record the AMO data-collection message in the catalog snapshot (6a165dda)
- Scaffold the AMO data-collection key; warn on key-less Firefox builds (c3edd7cb)
- Remove non-policy comments from test files (0b08d787)
- Keep the watcher alive when a mid-save manifest is invalid JSON (0a7e4de5)
- Self-ignore dist/extension-js so session state never gets committed (e9b97e76)
- Persist the build summary contract for hosts that shell out to build (602fc4e9)
- Route browser-generated CDP Log warnings into the bridge log pipeline (4203a88e)
- Align doctor specs with the unknown browser-liveness verdict (d23730d2)
- Honesty cluster: doctor unknown verdict, stub warning text, zip locale (639e600b)
- Reach url-override extension pages via the surface relay (cbd73b53)
- Keep MV2 dev background persistent and drop stale Firefox startupCache (4639973a)
- Warn when user code relies on dev-injected permissions, align MV2 set (0c186ff2)
- Never rewrite a live dev session contract from build/preview/start (beb2112c)
- Stamp unexpected browser exits for Firefox and preview, flip run-only (40445fa8)
- Stamp ready.json stopped at watch close and keep errored manifests watched (cd202bc6)
- Trace offscreen.createDocument urls so offscreen documents ship in dist (7ec27d80)
- Ban explicit any across every program, leaving specs and the fork (60f9e00c)
- Ban explicit any across the develop program source (80df0e10)
- Ban explicit any in the CDP and RDP browser clients (28f32e50)
- Ban explicit any in plugin-web-extension and type its boundaries (2d3a3425)
- Apply the safe autofixes for five style and import lint rules (18ff32b5)
- Retire the deferred lint warnings and make two suspicious rules errors (1affa370)
- Cover the bridge injection steps and the whole CLI command surface (a869e1cc)
- Unwrap the async promise executor in CDP connect and ban the pattern (c022fab6)
- Cover the reload strategy background entry and MAIN world bridges (9e622646)
- Give the browser connection errors a cause and a next step (6b16c36c)
- Clear em dashes from source and guard against new ones (634da2a9)
- Replace the 23.6MB typescript dependency with rspack's swc and acorn (1a523c6c)
- Make the lint gate real and restore the pre-commit hook (5cff9be5)
- Scaffold moduleResolution bundler; node is gone in TypeScript 7 (a22c9a3d)
- Split typescript: runtime stays on 6.x, tooling moves to 7.0.2 (a3911527)
- Fetch create templates via codeload tarball, not a full git clone (7d7da9cc)
- Pin a resolved engine version in scaffolds instead of floating latest (0fd9ca5e)
</details>
4.0.13 (July 19, 2026)
Features
- Add --no-polyfill, emit extension-develop dts, fix stale --source help (79683f72)
- Add --parent-pid watchdog so leaked dev servers die with their owner (63be66fa)
Fixes
- Resolve HMR runtime from @rspack/core so Yarn PnP resolves it (#486) (58ffa0ae)
- Resolve browser-prefixed world keys before MAIN-world bridge compilation (6a5ba99f)
- Sweep reload-era dead code from browsers; trim README deno note (edcd00ac)
<details>
<summary>Other changes (4)</summary>
- Prune superseded hot-update generations from the loadable dev dist (28602698)
- Stamp real command + versions in ready.json; per-run events.ndjson (4147cda9)
- Slim feature-scripts: drop dead shims, unify compilation issue reporting (032909df)
- Extract reload/HMR into plugin-reload; hoist content-script wrapper (c702350b)
</details>
4.0.12 (July 17, 2026)
- extension doctor, one command that walks a dev session's control-channel legs (ready contract, server process, ports, token, executor, browser) and names the first failing one with a fix. Agents get --output json.
- Fork-browser fixes, waterfox/librewolf now get Firefox-shaped web_accessible_resources, and brave/opera/vivaldi/yandex now get the MV2-deprecation warning Chromium targets already had.
- Clearer control-channel errors, "no executor connected" and eval "Forbidden" now say why (stale service worker mid-resync, browser still launching, missing/mismatched eval token) instead of a catch-all.
Fixes
- Fix control-port spec: resolve() adds drive letter on Windows (d4bc93b9)
- Prevent #484 class: per-browser token, doctor verb, session smoke CI (68511174)
- Fix deno smoke lane: deno install ignores file: deps; use links field (0a753eae)
- Stop claiming Preact HMR in author-mode summary and dev help (e0c0c26e)
- Fix npm README logo rewrite regex; resync generated mirror (8038d0d5)
- Repair named commands missing descriptions Chrome refuses to load (047e2209)
<details>
<summary>Other changes (16)</summary>
- Extract inline script by string index, not regex (CodeQL #73) (e788ecee)
- Trace webpack numeric chunks + runtime-set HTML surfaces into dist (29489317)
- Normalize folder ASCII banners: add 113 missing, fix 20 wrong (e1a5b0d2)
- Remove resolved docs/followups and dead vitest.workspace.ts (965a9043)
- Log Firefox RDP connect retries and name the port on give-up (e3d3b799)
- Repo hygiene: drop dead files, fix docs drift, sync test workspace (96ef5038)
- Bridge classic page-script globals to window for inline consumers (9ffaa3e6)
- Root-absolute refs: ship JS import closure, fix manifest page targets (fd820dca)
- Resync generated npm README mirror (Safari status Alpha) (5105e379)
- Resync bundled javascript template: top-level setPanelBehavior fix (58d6a8f2)
- Reject failed builds as promises; process.exit(1) only via CLI opt-in (f5c3c649)
- Leave unresolvable bare require() verbatim instead of failing the build (c5ca4225)
- Canonicalize supported-surface lists; promote deno to full peer (2a78f2ed)
- CI: promote Deno to PR-gating smoke lane (validated locally) (d50b5ecf)
- CI: smoke fork build targets; add non-blocking nightly Deno lane (0d5a6cbb)
- README: note Deno support alongside npm/pnpm/yarn/bun (aaed6e47)
</details>
4.0.11 (July 17, 2026)
Features
- Add nightly macOS smoke for the real Safari toolchain pipeline (3ce254d4)
- Surface Safari xcrun/xcodebuild output; build skips packaging off-macOS (ed40d809)
Fixes
- Guard bundled javascript template against examples drift (dc729329)
- Resolve safari:/webkit: manifest prefixes; warn before project regen (72a5da8d)
- Repair missing version and CSP unsafe-inline; diagnose unsupported MV (dd9845b4)
<details>
<summary>Other changes (6)</summary>
- Resync bundled javascript template with examples repo (1fc0f7fb)
- Align Safari app/appex bundle ids to --bundle-id after conversion (b0e86e4f)
- Safari status to Alpha; install explains Xcode instead of a binary (9fad813b)
- Wire Safari identity options: --bundle-id/--app-name + config support (311967f6)
- Record Safari converter as a non-surface for manifest refusals (3036e779)
- Diagnose live-verified Chrome manifest refusals; repair bad names (8315a492)
</details>
4.0.10 (July 15, 2026)
Fixes
- Stop emitting assets on errored compiles so dist keeps last-good (57a18b1c)
<details>
<summary>Other changes (5)</summary>
- Strip emojis from generated release notes (1c3f4be8)
- Ship real compile-error text in ready.json and events.ndjson (8f7bd584)
- Print dev command failures cleanly without a stack trace (f8433602)
- Latch content-script reloads until the SW acks, replay on hello (a194db39)
- Warn per file when scss/less ship uncompiled without their compiler (53c68dba)
</details>
4.0.9 (July 13, 2026)
🐛 Fixes
- Stop killing the dev browser on CDP stalls; surface its death (6cb4c8b7)
- Stop flagging wildcard ports in match patterns as launch refusals (e3b26c2f)
- Resolve root-absolute CSS url() from the extension root (a86e86c6)
- Resolve root-absolute refs and TS NodeNext .js import specifiers (aeb6c6fc)
- Stop flagging query strings and fragments as launch refusals (ed30159b)
<details>
<summary>🧹 Other changes (8)</summary>
- Loosen dev connect-src for the resolved connectable host (3c5474d0)
- Tolerate dead CSS url() refs; type-strip TS in classic-concat (268a23d7)
- Ship console-relay logs over a named Port to kill message loops (6a148b4b)
- Auto-install with --ignore-scripts; warn on dead HTML refs (fb24279c)
- Isolate devtools overlay shadow host from page styles (639e1c53)
- Raise RUST_MIN_STACK to 256MB so deep ASTs do not SIGILL rspack (8d05d544)
- Dedupe files listed twice in one content_scripts js array (b2cfc1e5)
- Content-hash dev asset names to stop same-basename collisions (78c2dce6)
</details>
4.0.8 (July 12, 2026)
🚀 Features
- Add EXTENSION_BROWSER_FLAGS env pass-through for launch flags (9d574295)
- Add getURLDependencyMissing to the messages-catalog snapshot (ea8a8859)
🐛 Fixes
- Stop flagging explicit ports in match patterns as launch refusals (b62b33b8)
- Repair 0-byte manifest icons and diagnose unloadable icons at launch (5776ac7e)
- Repair non-numeric manifest version strings at emission (0d3f3aff)
- Resolve root-URL HTML refs against the manifest root, not dist (d2c92f74)
- Repair manifest shapes Chrome refuses and diagnose MV2 on Chromium (7c8399df)
- Harden dev reload delivery: empty background, CSP origins, load errors (3b06ccef)
<details>
<summary>🧹 Other changes (27)</summary>
- Fan shared SW+content module edits to both reload paths and heal tabs (8e833828)
- Pick the HTML HMR API by the source's own module syntax (17a6b852)
- Name the manifest shapes Chrome silently refuses at launch (ce14782a)
- Strip the UTF-8 BOM before the manifest read in emit-html-file (020715a2)
- Ignore watch paths by segment instead of substring (d19d070b)
- Warn at launch on match patterns with query, fragment, or port (85e2669d)
- Diagnose Firefox-style MV3 background.scripts at Chromium launch (665d8cb2)
- Inject module.hot into script-parsed page scripts, not import.meta (41f23d2f)
- Keep import(chrome.runtime.getURL(...)) native in emitted bundles (cfb61f27)
- Ship the static import closure of runtime-traced modules (1f6043df)
- Update messages-catalog snapshot for fatalManifestShapeFixed (4c05318c)
- Fail the build when an emitted content script does not parse (7d5ad766)
- Honor exclude_matches in dev reinjection and re-registration (7120bf70)
- Keep dev reloads deliverable to idle MV3 service workers (1d8fb08e)
- Point css-only content_scripts groups at the emitted entry chunk (76552107)
- Compare requested vs resolved dev-server ports numerically (e3cf24cd)
- Name the resolved browser binary and stop stale snapshot outranking (1e6fa66f)
- Survive Chromium 152 dev reloads and merge repeated feature switches (4d3dd33a)
- Bound the telemetry audit log with a size-cap rotation (538c5cb3)
- Scaffold deno.jsonc and make the toolchain manifest-agnostic (#482) (70385b8c)
- Persist the dev control port outside dist for SW resync (#484) (7bb0d820)
- Classify dev reloads by chunk graph and clamp asset names to output dir (860201f0)
- Identify dev-server runtime modules by content, not require position (e3a17b60)
- Fall back to manifest directory when a project has no package.json (0e836d08)
- Always rebuild bundled companion extensions; fix CDP port from --port 0 (b6c4ff3e)
- Qualify content-script wrapper ownership by extension id (cb16fcf6)
- Trace chrome.runtime.getURL literal targets into dist (9c1fcad1)
</details>
4.0.7 (July 11, 2026)
🐛 Fixes
- Resolve PostCSS config string plugins project-first so CLI installs outside the project can load them (2d13a9dc)
- Resolve .env files family-wide and make undefined env vars safe (2c449344)
<details>
<summary>🧹 Other changes (8)</summary>
- Fail the build when manifest page surfaces (popup, options, overrides, devtools) point at missing files (8f59a72e)
- Trace runtime-fetched package files into dist and keep executeScript tracing alive past multi-KB template literals (648d23f2)
- Confine project auto-install to the project dir and fall back to npm when the resolved package manager fails (65f671af)
- Type ?inline stylesheet imports as asset/source so Vue custom-element styles resolve to CSS strings (8bff845b)
- Match link rel as a token list so shortcut icon assets stay static instead of becoming phantom stylesheet modules (dd7d1aae)
- Update all *-location dependencies (72533594)
- Concatenate classic multi-script HTML pages into one shared scope (8af0b2fb)
- Trace importScripts deps and executeScript file payloads into dist (2cc9c9a9)
</details>
4.0.6 (July 7, 2026)
<details>
<summary>🧹 Other changes (3)</summary>
- Fall back to any managed chromium-family binary when the requested chrome/chromium is missing (a13b6aaf)
- Cover chromium in install all and fall back to managed chromium-family binaries when dev's default chromium is missing (e5956fda)
- Update README.md (3985a105)
</details>
4.0.5 (July 5, 2026)
🐛 Fixes
- Fix Safari extension-URL scheme in CSS url() and import.meta minification in vendored ESM chunks (6246eed3)
- Fix classic-concat content-script CSS/MV2 background emission and vendored UMD require build break (3950253e)
<details>
<summary>🧹 Other changes (16)</summary>
- Compare path sets against rspack resources through one resolved toResourceKey (8469e2c9)
- Pin swc rules to explicit javascript/auto so the project package.json type field cannot override browser-parity script-vs-module detection (419748fe)
- Tolerate UTF-8 BOM in all extension JSON parses and route preprocessor stylesheets as plain CSS when the preprocessor is not installed, matching Chrome loading (dd8439e7)
- Announce dev reloads with one server-built context label across CLI stdout, the page devtools console, and the devtools pill, and self-heal stale cached service workers via a persisted control port and broker resync (f5e3d846)
- Lead npm and README metadata with the cross-browser extension framework positioning (85f8c057)
- Emit HTML static assets at their source paths so runtime references resolve like Chrome serves them (56922215)
- Accept web_accessible_resources match patterns with ports and port wildcards that Chrome loads instead of failing the build (582e3b45)
- Parse page scripts as javascript/auto and force ESM only where the platform declares it (script type=module, module service workers) (8f5deca8)
- Auto-detect script vs module in swc-loader so classic sloppy-mode content scripts build like Chrome loads them (6c0fc548)
- Skip PWA web-app manifests when resolving manifest.json and re-resolve to the real extension manifest instead of crashing on PWA-shaped fields (f0d3f45f)
- Warn and ship invalid CSS verbatim instead of failing the build, matching browser error recovery (4af5697d)
- Preserve in-project icon paths in the output instead of flattening to icons/<basename> so same-name icons stop colliding (ab99df87)
- Emit a directory web_accessible_resources entry as its files plus a glob instead of crashing on EISDIR (967f6b39)
- Drop scripts/ files the extension never references so data and generator helpers stop breaking builds (cd5848ef)
- Emit both background keys when a manifest declares service_worker and scripts together instead of clobbering one to its raw path (3dc6ac68)
- Exclude Node build/dev tooling from the scripts/ special folder so it stops breaking builds (36be9dd7)
</details>
4.0.4 (July 4, 2026)
🐛 Fixes
- Resolve bundled sass-loader and less-loader hoisted beside extension-develop so npx and exec builds find them (0355b4a4)
<details>
<summary>🧹 Other changes (1)</summary>
- Disable Preact fast-refresh so the rspack 2.x prefresh runtime stops crashing dev with module is not defined (4f6380cc)
</details>
4.0.3 (July 1, 2026)
🚀 Features
- Support named browser forks via engine-family manifest keys and build/launch path (d7c903f4)
🐛 Fixes
- Harden Firefox banner add-on id fallback to refuse ambiguous guesses (d776e4d9)
- Resolve bundled CSS preprocessor loaders via rspack resolveLoader.modules instead of manual path resolution (8059fc62)
<details>
<summary>🧹 Other changes (10)</summary>
- Drop four dead develop exports and rename the firefox follow-up to match its content (ca49dd54)
- Rename the source-inspection dirs to cdp/ and rdp/, upgrade the firefox id follow-up (c3dabd31)
- Remove dead controller methods left by source-inspection and pair up chromium/firefox (53331d86)
- Remove the unwired source-inspection feature (a2afe400)
- Remove dead code across create, develop, and extension (6b8c47dc)
- Single-source optional-dependency install hints from bundled versions and drop dead signature helper (4e6da9a7)
- Make the not-emitted manifest guard version-aware instead of blaming incremental builds (df9c51d3)
- Bump bundled less to 4.6.7 to drop the errant 4.5.1 postinstall that trips build-script warnings (f4cc754a)
- Detect the Deno runtime so scaffolds suggest deno install and deno task commands (fd9f869b)
- Pre-approve dependency build scripts in scaffolds so install-once just works (7218b099)
</details>
4.0.2 (July 1, 2026)
🚀 Features
- Add ci:test:create job so create specs run in CI (f677cd93)
🐛 Fixes
- Resolve chromium manifest keys for Safari and unify the browser-key resolver (76a43795)
<details>
<summary>🧹 Other changes (5)</summary>
- Explain where there other templates are hosted (#477) (6eda9f84)
- Register a default background entry for Safari and version-less manifests (a1f38e1c)
- Compile create before its tests and gate env-fragile install specs under CI (f54baeda)
- Complete the init-alias create test so it actually imports the template (a34fda8a)
- Strip examples-repo scaffolding files from scaffolded projects (54f0f4f1)
</details>
4.0.1 (June 30, 2026)
- Extension.js v4, now on Node.js 22+. Node 20 is no longer supported. There are no API changes: upgrade Node and your project keeps working.
- Multi-file content scripts just work in dev. Split a content script across plain files (a base class in one, the rest in another), saves now hot-reload without a restart, and a thrown error traces back to your real file and line instead of an inlined blob.
- Snappier Safari dev. extension dev --browser=safari resyncs in the background instead of blocking on a full Xcode build every save, and a burst of saves collapses into a single rebuild.
- No leaked browsers. A dev session that exits on its own now reliably shuts the browser down, no more Chrome or Firefox processes lingering after you're finished.
🚀 Features
- Add regression test for @rspack/plugin-react-refresh named export resolution (8a1b50e0)
- Expose FileConfig type at package level for extension.config.js (#468) (93577be9)
- Support @rspack/plugin-react-refresh v2 export shape and align the contract to 2.0.2 (3290e85b)
- Add v4 release highlights (57c333d0)
- Surface swallowed Chromium source-inspection failures through author-mode diagnostics (e0f74b69)
- Surface swallowed locale-validation failures through author-mode diagnostics (3caf5029)
- add Brave, Opera, Vivaldi, Yandex, Waterfox and LibreWolf as browser targets (fdb3f2ed)
- Forward profile keep/copy options through the firefox launch request (2cbf9d8d)
- Forward copyFromProfile/keepProfileChanges from config through to the chromium and firefox launchers (b214f23c)
🐛 Fixes
- Override js-yaml, form-data, vite and read-yaml-file to clear dependabot security advisories (3930424e)
- Resolve CDP/RDP port per browser instance so a second instance cannot capture the first's port (921fdc1f)
- Fix theme additional_backgrounds array crash and chrome-extension:// CSS URLs (ad86c34c)
- Fix page-script top-level await and stop wrapping vendored *.min.js (19189abb)
- Fix WAR parity gaps w/ extension compiler (851c47d1)
<details>
<summary>🧹 Other changes (44)</summary>
- Route isSubPath through the shared resource-path helper for cross-platform consistency (900071dc)
- Centralize resource-path canonicalization in a shared, cross-platform helper (4b938754)
- Match content-script loader include via canonicalized resource path for Windows (9300fb30)
- Canonicalize content-script resourcePath so wrapping works on Windows (e878bf64)
- Emit prefixed manifest entries for engine-family browser targets (b4fd0431)
- Drop the duplicated command name from CLI usage strings (eba667e1)
- Use the launched Firefox RDP port verbatim instead of re-deriving it (4398fc80)
- Run launched Firefox headless when MOZ_HEADLESS is set (e8fed0d4)
- Unify reload through the extension service worker for launched and --no-browser browsers (7a330aa7)
- Reload content scripts under extension dev --no-browser and add a connectable host (a55444f8)
- Probe the dev server port on the configured host (0faa8342)
- Inherit chrome:/firefox: manifest keys for browser forks (c9280248)
- Parse optional-boolean CLI flags so --flag false disables them (0b50bd3e)
- Update dependencies for Node 22 (7a4a269c)
- Drop Node 20: bump CI and engines.node to 22 so yarn installs resolve which@7 (ea1c978b)
- Update message-catalog snapshot for the new firefox-reinject and chromium source-inspection messages (80a88df6)
- Coalesce Safari dev packaging so saves resync in the background and bursts collapse to one rebuild (34c11c8f)
- Type the Firefox RDP wire boundary and client so wrong shapes fail the compile (4be1701f)
- Type the Chromium runner's CDP wire boundary so wrong-shaped protocol data fails the compile (0af6f5b1)
- Force-kill the browser synchronously on process exit via a shared teardown module (66b79e08)
- Watch and source-map classic multi-file content scripts via a dedicated concat loader (553d9dbd)
- Route Firefox runtime-reinjection failures through the messages convention with author-mode diagnostics (fc852022)
- Exclude TypeScript declaration files from script entries (e94bef25)
- Warn when building a Manifest V2 extension for a Chromium target (8df0d895)
- Concatenate and dedupe MV2 background.scripts output (22b8a732)
- Concatenate classic multi-file content scripts so they share one scope (d8b15336)
- Pin which to ^4 so browser-location packages stay Node 20 compatible under yarn (554e9161)
- Declare keepProfileChanges/copyFromProfile on BrowserConfig so the dev config typechecks (90b97113)
- reuse wsl-support package for generic WSL primitives (0d5c4cf2)
- Warn (don't fail) on missing CSS url() assets and pass the url through (8bf09fec)
- reuse prefers-yarn helpers in develop package manager (66477cdc)
- import Compiler type explicitly in rspack config (216a71ed)
- reuse prefers-yarn for package manager detection in create (dbb29ccb)
- Relocate leading-slash icon paths to icons/ so the manifest matches the emitted files (b65a4af2)
- Seed copyFromProfile once so kept profiles are not clobbered on later runs (6fb4375d)
- Update message-catalog snapshot for the new Safari resync messages (bfe4f8cd)
- Type 41 manifest-shape casts to drop any so wrong-shaped manifests fail the compiler (69c522e7)
- Throw a readable PM-aware install hint for missing optional deps instead of a raw JSON blob (c6c9a97b)
- Honor profile:false, copyFromProfile and keepProfileChanges via shared resolve-profile (135349df)
- Treat unknown chromium extension ownership as not-owned to avoid adopting foreign extensions (65ab2dbd)
- Re-run Safari converter on manifest changes and preserve Xcode user settings on --force (89510a40)
- Bump browser-extension-manifest-fields to ^2.2.5 (8c9ea9d8)
- Emit theme image files (theme/images/<basename>) (d553ebf1)
- Exit non-zero when compilation errors prevent output (ef662f9f)
</details>
4.0.0 (June 30, 2026)
🚀 Features
- Add open action/command bridge triggers and fix Firefox extension loading (RDP addons actor cache, background producer injection, service_worker→scripts) (a3c0b8aa)
🐛 Fixes
- Fix smoke:npx for workspace specifiers and wire it into CI as a packed-tarball guardrail (0a8a0963)
<details>
<summary>🧹 Other changes (3)</summary>
- Delete dormant feature-resolve and drop @swc/core and magic-string (2fe00f58)
- Use es-module-lexer instead of @swc/core for content-script default-export detection (1142eb11)
- Remove dead dependencies from extension-develop (cross-spawn, unique-names-generator, loader-utils, @swc/helpers) (4514eae6)
</details>
3.18.0 (May 28, 2026)
🚀 Features
- Surface real CDP port into ready.json for out-of-process source inspect (f2236401)
- Add the extension publish command for a shareable url (af6769c3)
- Inspect extension surface dom through the in bundle relay (dd152b9a)
- Add the agent bridge act and inspect slices with multi context logs (e9009e3a)
- Add the extension logs command to read and stream the bridge (2444e38e)
- Add the agent bridge consumer client and ready contract reader (54666257)
- Forward background console output over the control websocket (1455e882)
- Add the agent bridge slice 1 control websocket broker and log file (bbc964bc)
- Add CI lint/typecheck gate, readiness schema, producer tests, and reload-matrix smoke (cd3ada54)
- Enhance zip download mechanism (78bcbeb9)
- Bundle default create template, fix package-manager detection and network timeouts (038756dc)
- Add (alpha) Safari target support and Chromium/Firefox runner hardening (a2ea122f)
🐛 Fixes
- Bump ws to ^8.20.1 to patch GHSA-58qx-3vcg-4xpx (cb2a6268)
- Restore the @rspack/[email protected] SCAFFOLD_OVERRIDES workaround (c5fad156)
- Ensure build also produces the extension.d.ts file (c5725a23)
- Fix the three CI failures revealed once the lockfile was synced (464d7c81)
<details>
<summary>🧹 Other changes (11)</summary>
- Raise perf-budget defaults to 512/512/1024 KiB (df09459e)
- Drop the scaffold-overrides workaround for the @rspack/dev-server 2.0.2 break (50ddc5af)
- Remove the implemented readiness design docs (8420f830)
- Snapshot the 21 messages.ts catalogs (readiness item 5c) (c4403d7b)
- Remove the implemented agent bridge and distribution design docs and fix code comments (38227bc0)
- Pierce closed shadow roots in dev source deep dom (f4db965d)
- Declare the ws dependency for the control bridge (a0777eab)
- Declare webpack devDep in develop so typecheck gate resolves the vendored HMR fork (f1300126)
- Unify package-manager detection across yarn and bun (736e1c08)
- Review cleanup of extension package (f5c6ae92)
- Develop plugin review cleanup, hardening, and browser process shim (74de1bdd)
</details>
3.17.0 (May 21, 2026)
🐛 Fixes
- Bump svelte to 5.55.9 to clear Dependabot XSS advisories (4cc441cd)
<details>
<summary>🧹 Other changes (2)</summary>
- Write dev manifest.json in afterEmit and switch content-script hashing to contenthash (ea94d73a)
- Write dev manifest.json in afterEmit and switch content-script hashing to contenthash (d8c17912)
</details>
3.16.1 (May 14, 2026)
🐛 Fixes
- Bump fast-uri to ^3.1.2 to clear Dependabot path-traversal + host-confusion advisories (b49c9b13)
- Sweep orphan content-script roots and ignore current-build roots in cleanupKnownRoots (ecfce860)
- Gate devtools overlay at content-script entry and harden launcher UX (a0c745f9)
- Gate devtools overlay at content-script entry and harden launcher UX (5300edc8)
<details>
<summary>🧹 Other changes (5)</summary>
- Replay programmatic chrome.scripting.executeScript calls on /scripts/* edits (ede537be)
- Only warn for genuinely new files in pages/ and scripts/, not modifications (ee26b765)
- Auto-resolve workspace subpackage when extension dev is given the monorepo root (32e06114)
- Honor namespaced manifest_version in SetupBackgroundEntry default background entry (28533531)
- Derive Chromium extension ID from load path when no manifest key + no runtime target (03ffef5b)
</details>
3.16.0 (May 7, 2026)
<details>
<summary>🧹 Other changes (6)</summary>
- Ignore benign socket teardown errors in browser process handlers (Templates Nightly Edge ECONNRESET) (385c955e)
- Force-exit optional-deps smoke after main() so Linux orphans don't hang the CI step (ddfaeed9)
- Compile extension-develop before vitest so dist-shape spec has artifacts (10b87eb7)
- Scope ESM banner to Node-side bundles and add regression gates (57b14c87)
- Flip extension-develop to ESM output for @rspack/core@2 compatibility (a589d63e)
- Update WASM example link in README (e9caf210)
</details>
3.15.1 (May 5, 2026)
🚀 Features
- Add regression test for PreactRefreshPlugin preactPath option (a0d1fa98)
- Add regression tests for module-context-resolve project-package fallback (b2e6911b)
- Add remote-mode and template-name fixture resolution to reload-matrix harness (017ce0fe)
🐛 Fixes
- Stop firing chrome.runtime.reload for page-only edits in non-content-script extensions (76add731)
<details>
<summary>🧹 Other changes (14)</summary>
- Update preact.spec assertions to match package-directory preactPath (80047082)
- Pass preact package directory to PreactRefreshPlugin (not entry file) (2e235377)
- Pass project preact path to PreactRefreshPlugin for pnpm strict layouts (5580a757)
- Raise content-script perf budget to 256 KiB for framework templates (1812a011)
- Apply project-package fallback to module-context-resolve rules (4b6b329e)
- Trust project package.json when pnpm symlinks hide the contract dep (5e0a0f79)
- Suppress executionContextCreated burst on watched-session attach (05d9195a)
- Preserve sibling content_scripts entries during dev reinject (78a2c1fb)
- Inline content-script CSS as data URLs to close the WAR gap on rspack 2.x (0120b2db)
- Relocate reload-matrix harness to _FUTURE/examples per workspace convention (a5706d7c)
- Extend reload-matrix harness with multi-scenario runner and 5-row matrix (ed3c294e)
- Scaffold reload-matrix CDP harness for ground-truth reload measurement (65df59c1)
- Revert "Serialize and coalesce reload requests at the controller boundary" (07c16fd7)
- Serialize and coalesce reload requests at the controller boundary (daf8e451)
</details>
3.15.0 (May 4, 2026)
🚀 Features
- Add per-category perf budgets tuned for browser-extension workloads (546664d0)
- Add script to inventory perf warnings across _FUTURE example builds (5d5478b5)
🐛 Fixes
- Prevent companion extension duplication (c0e710cd)
- Stop installing unused firefox/chromium in cli CI suite to dodge snap hang (19103082)
- Fix nightly CI template builds and the playwright-core resolution (21d0dde5)
- Stop devtools companion from toggling user extension via chrome.management (2716143f)
- Resolve _locales at the project root and reject manifest-dir layout (8f5f655d)
- Fix manifest/SW/locale reload classifier and lock companion-targeting in tests (e90ee3e9)
- Stop passing chromium-only flags to Firefox launch (d2d20aaa)
- Gate chromium-only background listeners in extension-js-devtools (0e172667)
- Stop manifest icons diff from firing spuriously on every rebuild (c56a175b)
- Fix bad output of the (re)compilation banner (b67a444e)
- Stop extension-develop resolver from escaping node_modules into outer monorepo (2ddfc9b9)
- Fix HTML live-reload regression on rspack 2.x and lock the contract in tests (65d38ee5)
- Restore content-script wrapper in production to keep mount call alive (6220725c)
<details>
<summary>🧹 Other changes (21)</summary>
- Fire chrome.runtime.reload() once per save instead of N times racing on the eval response (60745b23)
- Anchor relative profile paths to the rspack context so sequential examples do not share one profile (727d9b29)
- Bump browser-extension-manifest-fields (4b37af31)
- Pick user extension over companion when version + manifest_version tie (0705456d)
- Compile extension CLI on demand from companion Firefox MV3 spec (f0200792)
- Update README.md (43042601)
- Dedupe extension load list and ignore companion shadows of built-in packages (021d789e)
- Skip dependency install in web-only mode to fix extension dev crash on Chrome samples (70d41a67)
- Rework README with growth-oriented hero, comparison table, and ship-to-store guide (6e292dfa)
- Lock in companion-extension Firefox bundle as MV3-API-free (c72dadab)
- Force single Playwright worker to eliminate content-reload spec race (b5f4b85f)
- Hold firefox apt package so --with-deps does not trigger snap install (bb4c6f28)
- Soften strict _locales layout policy from build error to warning (4cc4f82d)
- Mark generated templates/package.json as ESM to keep spec imports working (19ceeb99)
- Teach perf-warning inventory to parse the new PerfBudgetWarning block (ada3b652)
- Discriminate page vs content errors in devtools dialog by script origin (599fc7dd)
- Pick newest content-script bundle by mtime so reload reflects latest rebuild (f38f3060)
- Make Firefox welcome tab open reliably on first run (9cf4dae8)
- Normalize watch path separators in dev-server config spec for Windows CI (c50d2b8e)
- Normalize watch path separators in dev-server config spec for Windows CI (27400eb2)
- Drop dist-build dependency from minimum-script-file/preact-refresh-shim specs (415f505f)
</details>
3.14.5 (April 25, 2026)
🐛 Fixes
- Resolve CJS requires via the require exports condition (#445) (c4e85e43)
3.14.3 (April 24, 2026)
🚀 Features
- Add content-script reload regression tests (0ff04cf7)
🐛 Fixes
- Restore the per-rebuild "compiled successfully" stdout line in browser-launch mode (271297e7)
- Fix content-script hot reload (47a067a0)
<details>
<summary>🧹 Other changes (3)</summary>
- Pin uuid >=14 to close Dependabot alert 143 (2a6fb8d8)
- Cover fresh tabs and page reloads for content-script edits (55c80040)
- Scope browser-root auto-attach to extension targets, silence debugger infobar (e31853fa)
</details>
3.14.2 (April 22, 2026)
🚀 Features
- Forward extension.config.js browser/command fields to the browser launcher (28b585b0)
3.14.1 (April 22, 2026)
🚀 Features
- Surface reserved-folder diagnostic for Node.js scripts dropped into scripts/ (7bac8509)
<details>
<summary>🧹 Other changes (1)</summary>
- Disable module concatenation in dev to fix react-refresh __webpack_module__ clash (c2b2b66f)
</details>
3.14.0 (April 21, 2026)
<details>
<summary>🧹 Other changes (4)</summary>
- Drop ?url query bypass in CSS loaders, add end-to-end regression spec (eda750a2)
- Pin @rspack/dev-server to ^1.2.1 until @rspack/core 2.x ships stable (794e400c)
- Default --install to off on extension create (135c58cc)
- Collapse CLI telemetry to 2 events with sampling, cap, and dedup (c87ef941)
</details>
3.13.5 (April 11, 2026)
🐛 Fixes
- Fix --port 0 (OS-assigned port) crashing the dev server (eb729298)
3.13.4 (April 11, 2026)
🐛 Fixes
- Fix user project dependency resolution for pnpm dlx and npx builds (a0b44bfa)
<details>
<summary>🧹 Other changes (1)</summary>
- Respect --install flag to skip dependency install in build/dev commands (298dd072)
</details>
3.13.3 (April 11, 2026)
🚀 Features
- Add browser spec tests for CDP and RDP transport layers (ce48d811)
🐛 Fixes
- Fix release pipeline changelog filters and apply lint formatting (9a7c5d58)
- Fix stale programs/cli path in first-dev smoke script (40c54ff8)
- Harden browser CDP/RDP reliability and observability (8b29b85d)
<details>
<summary>🧹 Other changes (2)</summary>
- Remove dead code, extract shared utilities, fix signal race, simplify core plugins (ddaabbd0)
- Make extensionCreate API/AI-friendly with injectable logger and structured result (9508cbfd)
</details>
3.13.0 (April 9, 2026)
🚀 Features
- Add Linux CI Chromium sandbox flags for CDP dev tooling (0181e730)
- Add BuildEmitter event API to extension-develop (6c4b9927)
- Add lightweight preview entry to develop for fast extension preview (a4cfb862)
🐛 Fixes
- Resolve release notes range when stable tag is off current branch (34ce0187)
<details>
<summary>🧹 Other changes (3)</summary>
- Remove extensionStart from develop. CLI now orchestrates build + preview (cc329680)
- Orchestrate start command with separate build + preview calls (b9ad1987)
- Optimize GitHub Actions workflows for faster CI (a6c08068)
</details>
3.12.1 (April 9, 2026)
🐛 Fixes
- Fix CDP race condition, log leak, globalThis state, and MAIN world manifest persistence (1b220bb9)
3.12.0 (April 9, 2026)
🐛 Fixes
- Fix CVE-2026-22028 preact VNode injection and CodeQL code sanitization alert (5b1bd6da)
- Fix CodeQL Firefox inspection and harden dev-server client resolution (8b82011d)
- Resolve HMR client paths from extension-develop at injection time (c2650714)
<details>
<summary>🧹 Other changes (8)</summary>
- Default create template to javascript and make template option optional (cd457fe1)
- Use workspace:* for extension dev dependency (ea7982da)
- Remove isolated-deps and bundle extension-develop toolchain (ed284849)
- Use geometric triangle prefix for signature log lines across CLI and webpack (70d5d95b)
- Update Vite/Vitest (81f3e250)
- Normalize path separators in HMR entry assertions for Windows (e4a7f83e)
- Bump go-git-it to 5.1.5 (0ec2602e)
- Show Firefox add-on ready line in dev and align ready copy (10067e85)
</details>
3.11.1 (April 8, 2026)
🚀 Features
- Add strip and remove dev server runtime from content script bundles (d3e10aac)
- Add canonical content script naming contracts and entry helpers (aa8f4b17)
🐛 Fixes
- Fix CI workflow script name and Windows path double-slash normalization (3e4bd2ca)
- Fix pre-existing test failures in dev-server and update-manifest specs (eb35a151)
- Fix Firefox content reload parity with Chromium (80eb7fde)
- Fix Chromium content reload: suppress manifest reason, reload extension after reinject, await controller (200d1576)
- Resolve hashed content script filenames in CDP controller for reinject (95d09c87)
<details>
<summary>🧹 Other changes (10)</summary>
- Ignore programs/create/.npmrc so local npm tokens are never committed (97576321)
- Normalize Windows drive slashes after backslash replace (c3478484)
- Replace in-tree optional-deps installer with isolated-deps package (821c6b22)
- Simplify reload internals before release (4b574838)
- Consolidate ci-scripts into scripts and remove dead scripts (21e04fac)
- Update changelog and companion extension adjustments (30262963)
- Refactor browser plugins, CDP/RDP inspection, and dev server internals (97ec810d)
- Wrap extension messaging sendMessage in try-catch in chunk loader (a8d6e2a0)
- Hash content script filenames in dev mode to bust browser cache on hard reload (ba3e497d)
- Rewrite content script wrapper with reinject lifecycle and cleanup registry (89f5ae4a)
</details>
3.10.3 (April 8, 2026)
🐛 Fixes
- Fix Windows optional dependency installs and smoke coverage (f675ad54)
- Fix content script CSS fallback restoration (7c3321f2)
<details>
<summary>🧹 Other changes (1)</summary>
- Offload browser discovery to location libs (6e5746df)
</details>
3.10.2 (April 8, 2026)
🐛 Fixes
- Fix content script manifest CSS restoration (3f7517cc)
<details>
<summary>🧹 Other changes (2)</summary>
- chore: sync build deps tracking manifest (c5622538)
- Bump dependency bundle and clear audit alerts (6b01a343)
</details>
3.10.1 (April 8, 2026)
<details>
<summary>🧹 Other changes (11)</summary>
- Added -b shortcut to browser option (#430) (cca28133)
- Stabilize Windows pnpm smoke workspace paths (aa09acb5)
- Stabilize Windows npm optional dependency preflight (daaca4e0)
- Handle cross-drive Windows file specifiers in pnpm smoke (df7f9d5f)
- Align pnpm optional-deps smoke with source-under-test (1aad9776)
- Generalize optional dependency contracts across webpack tooling (3cb55980)
- Enforce transactional optional dependency installs (de00809c)
- Setup internal standalone library for installing and resolving on-demand tooling (f57cd715)
- Setup internal standalone library for installing and resolving on-demand tooling (20c0b6b9)
- Stabilize CI platform-specific optional deps assertions (8735e20c)
- Setup internal standalone library for installing and resolving on-demand tooling (dfe59ce2)
</details>
3.10.0 (April 8, 2026)
🐛 Fixes
- Fix excludeBrowserFlags forwarding in dev config (40eba59c)
- Fix optional dependency installs across framework tooling (c88e7b62)
- Fix Discord release not working (1f332396)
3.9.5 (April 8, 2026)
🐛 Fixes
- Fix GitHub Actions Node 24 deprecation warnings (3e4f07f4)
<details>
<summary>🧹 Other changes (1)</summary>
- Preserve Rspack branding in optimization warnings (bd7874a4)
</details>
3.9.4 (April 8, 2026)
<details>
<summary>🧹 Other changes (2)</summary>
- Improve managed browser install guidance. (d7bcbcd8)
- Prefer the project-local develop runtime during create (41f2b912)
</details>
3.9.3 (April 8, 2026)
🐛 Fixes
- Fix Dependabot alerts (3791de9f)
- Fix React optional dependency installs for content dev (1840b091)
- Harden managed browser profile reuse (b2aeb980)
3.9.1 (April 8, 2026)
🐛 Fixes
- Fix Vue optional dependency installs for consumer builds (a402a25f)
3.9.0 (April 8, 2026)
🚀 Features
- Enhance output data view for performance hints (107da296)
🐛 Fixes
- Fix publish workflow (42243496)
<details>
<summary>🧹 Other changes (2)</summary>
- Generate curated stable release notes (7771574e)
- Richer build output (bef3ffc8)
</details>
3.8.16 (April 8, 2026)
🐛 Fixes
- Fix extension.config root resolution with src manifests (3d9d65d1)
<details>
<summary>🧹 Other changes (2)</summary>
- Preserve webpackIgnore comments in production builds (49d81f16)
- Preserve CLI spacer lines in Turbo-prefixed output (511b0e23)
</details>
3.8.14 (April 8, 2026)
🐛 Fixes
- Fix regression on optional deps install on Windows (6a0af460)
3.8.13 (April 8, 2026)
<details>
<summary>🧹 Other changes (1)</summary>
- Improve build warning summaries and remove contradictory success output (d2a9583b)
</details>
3.8.12 (April 8, 2026)
🚀 Features
- Add banner to --wait output (c317a32e)
- Add staging monorepo example as ignored (0e090593)
- Add --wait support for superior Playwright DX/AX (26300d30)
🐛 Fixes
- Fix rebase regression for the --wait output banner (76abe121)
- Patch vulnerable immutable transitive dependency (1e67066d)
<details>
<summary>🧹 Other changes (1)</summary>
- Improve --wait for start command (df1eb61d)
</details>
3.8.11 (April 8, 2026)
<details>
<summary>🧹 Other changes (2)</summary>
- Rename no-runner behavior to no-browser (1a4c845a)
- Invalidate optional-deps preflight cache when lockfiles change (c76331bd)
</details>
3.8.10 (April 8, 2026)
🚀 Features
- Support monorepo root env fallback for extension config loading (25cd214e)
<details>
<summary>🧹 Other changes (1)</summary>
- No loading for first-time optional deps install (1d6fb8a2)
</details>
3.8.9 (April 8, 2026)
🐛 Fixes
- Resolve 2 security vulnerabilities (#414) (98ab23b4)
<details>
<summary>🧹 Other changes (4)</summary>
- Scope optional peer runtime checks to Vue (43b84c70)
- Remove vulnerable serialize-javascript from build-deps lockfile (93c4be40)
- Hotfix for Vue examples not working (68e27a4d)
- Setup experimental error overlay (f2dbdbe2)
</details>
3.8.8 (April 8, 2026)
🚀 Features
- Add deterministic deep content-script reload validation. (e40f2072)
- Add more scripts to default creation projects (750f14f8)
🐛 Fixes
- Fix dependabot alerts (0819f9a7)
- Gate first-run canary reload regression (3fb0c8a1)
- Harden Chromium CDP startup against short-circuit failures (1be8a0b5)
- Fix warn-dev-mode spec logger mock typing (6d8c396c)
- Harden CDP extension ownership during first-run startup (e244ca42)
- Fix Chromium hard-reload test (a55e2d51)
- Fix first-run Chromium extension disable regressions (52128ca8)
- Fix hard-reload running on first runs and breaking UX (70fd0f5e)
- Avoid Chromium extension hard reload on initial dev build (13de5c11)
<details>
<summary>🧹 Other changes (4)</summary>
- Improve version resolution during create step (bca90b1b)
- Ignore dist output changes in hard reload watch detection (b5bfe8c0)
- Experimental error overlay (f1b66998)
- Auto-scan top-level ./extensions (49ccad57)
</details>
3.8.7 (April 8, 2026)
🐛 Fixes
- Fix .gitignore writing to avoid GC-closed file handles (d4f814a8)
3.8.6 (April 8, 2026)
🚀 Features
- Add tests to prevent built-in extension not bundling (e5b54eef)
🐛 Fixes
- Fix Windows path assertions in preview spec (4cd39ac6)
- Fix extension-create not running through Node.js interface (1210602b)
<details>
<summary>🧹 Other changes (1)</summary>
- Follow up on built-in extension overriding user NTP (5f4b4af3)
</details>
3.8.5 (April 8, 2026)
🐛 Fixes
- Fix bundled extensions regression (10028589)
- Resolve sass-loader in pnpm dlx one-run builds (3df92e47)
<details>
<summary>🧹 Other changes (1)</summary>
- Curate changelog entries for public release notes. (8bdd39b8)
</details>
3.8.3 (April 8, 2026)
🚀 Features
- Add automated optional-dependency smoke coverage across package managers (edacdc47)
🐛 Fixes
- Fix Windows file specifiers for local package overrides in smoke matrix (f1636b60)
- Fix Windows process spawning in optional-deps smoke runner (58b798c4)
- Fix optional-deps matrix portability across Windows, Yarn, and Bun (ed0ce77e)
- Fix optional-deps smoke matrix when browser-extension fixture is absent (2aee5550)
- Fix optional module loading fallback in pnpm CI layouts (3e42a165)
- Fix optional dependency resolution in pnpm canary CI (81bac7bc)
- Harden optional dependency runtime resolution deterministically (74297000)
<details>
<summary>🧹 Other changes (4)</summary>
- Further simplify install-root entrypoint resolution helpers (88f5b19d)
- Simplify optional dependency resolver control flow (941947e9)
- Codify optional-deps runtime contract and lock regressions (0f885a33)
- Use registry-mode extension for Windows pnpm smoke lane (e40e9568)
</details>
3.8.2
- Harden optional dependency runtime resolution to reduce first-run failures.
3.8.1
- No user-facing changes beyond release packaging updates.
3.8.0
- Add support for canary releases.
- Add an experimental install command.
- Improve Windows test and runtime reliability across Chromium, Edge, and Firefox flows.
- Improve path handling and source output behavior for more consistent CLI runtime output.
- Stabilize remote zip/template handling and companion loading defaults.
- Improve extension developer feedback by making Extension ID output more reliable and less noisy.
---
README
[npm-version-image]: https://img.shields.io/npm/v/extension.svg?color=0971fe
[npm-version-url]: https://www.npmjs.com/package/extension
[npm-downloads-image]: https://img.shields.io/npm/dm/extension.svg?color=0971fe
[npm-downloads-url]: https://www.npmjs.com/package/extension
[stars-image]: https://img.shields.io/github/stars/extension-js/extension.js?style=flat&color=0971fe
[stars-url]: https://github.com/extension-js/extension.js/stargazers
[action-image]: https://github.com/extension-js/extension.js/actions/workflows/ci.yml/badge.svg?branch=main&color=0971fe
[action-url]: https://github.com/extension-js/extension.js/actions
[discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat&color=0971fe
[discord-url]: https://discord.gg/v9h2RgeTSN
[snyk-image]: https://snyk.io/test/github/extension-js/extension.js/badge.svg?color=0971fe
[snyk-url]: https://snyk.io/test/github/extension-js/extension.js
Extension.js [![Version][npm-version-image]][npm-version-url] [![Downloads][npm-downloads-image]][npm-downloads-url] [![Stars][stars-image]][stars-url] [![CI][action-image]][action-url] [![Discord][discord-image]][discord-url]
The cross-browser extension framework. Build for Chrome, Edge, Firefox, and Safari with no build config required.
<img alt="Logo" align="right" src="https://avatars.githubusercontent.com/u/172809806" width="20.25%" />
npx extension@latest create my-extension
cd my-extension
npm run devWorks with npm, pnpm, yarn, bun, and deno.
Documentation · Templates · Examples · Discord
Why Extension.js
Browser extensions ship with the worst dev experience in modern web. Manifest V3 fragmentation, browser-specific quirks, no hot reload for content scripts, and a separate build pipeline for every target. Extension.js fixes that.
- Hot Module Replacement for background, content, popup, and options scripts, including React, Vue, Svelte, and Preact components
- Manifest V3 by default, with automatic adapters for Chrome, Edge, Firefox, and Safari targets
- One CLI for Chrome, Edge, Firefox, and any Chromium or Gecko binary
- Zero config, no webpack, no rollup, no plugins to maintain
- First-class TypeScript, React, Vue, Svelte, and Preact support
- Production builds with extension build --zip, ready for the Chrome Web Store and Firefox Add-ons
- Drop-in for existing extensions with one devDependency
Watch it work
Or skip the install and try a live template in your browser.
How is this different
If you have used Plasmo, WXT, or CRXJS, here is what Extension.js does that the others do not:
| Capability | Extension.js |
| :--------- | :----------- |
| Run any GitHub sample directly | extension dev https://github.com/.../sample |
| Managed browser binaries | extension install firefox downloads an isolated build |
| Cross-browser HMR for content scripts | Built in, no plugin glue |
| Production zip for the stores | extension build --zip |
| Framework agnostic | Vanilla, TS, React, Vue, Svelte, Preact, no lock-in |
| Custom Chromium and Gecko binaries | --chromium-binary, --gecko-binary |
Extension.js is sponsored by extension.dev, the platform that hosts the build, share and store submission side of shipping an extension. To hand someone an unpublished build behind a link, with no zip and no install on their side, see Share an unpublished build for review.
Frameworks
<div align="center">
| <img alt="ESNext" src="https://github.com/cezaraugusto/extension.js/assets/4672033/a9e2541a-96f0-4caa-9fc9-5fc5c3e901c8" width="70"> | <img alt="TypeScript" src="https://github.com/cezaraugusto/extension.js/assets/4672033/b42c5330-9e2a-4045-99c3-1f7d264dfaf4" width="70"> | <img alt="WASM" src="https://github.com/cezaraugusto/extension.js/assets/4672033/f19edff3-9005-4f50-b05c-fba615896a7f" width="70"> | <img alt="React" src="https://github.com/cezaraugusto/extension.js/assets/4672033/ff64721d-d145-4213-930d-e70193f8d57e" width="70"> | <img alt="Vue" src="https://github.com/cezaraugusto/extension.js/assets/4672033/15f1314a-aa65-4ce2-a3f3-cf53c4f730cf" width="70"> | <img alt="Svelte" src="https://github.com/cezaraugusto/extension.js/assets/4672033/de1082fd-7cf6-4202-8c12-a5c3cd3e5b42" width="70"> | <img alt="Preact" src="https://github.com/cezaraugusto/extension.js/assets/4672033/8807efd9-93e5-4db5-a1d2-9ac524f7ecc2" width="70"> |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| ESNext<br>Try out | TypeScript<br>Try out | WASM<br>Try out | React<br>Try out | Vue<br>Try out | Svelte<br>Try out | Preact<br>Try out |
</div>
Browsers
Use these flags with extension dev, extension start, or extension preview:
- Select a browser: --browser <chrome | edge | firefox | safari>
- Custom Chromium binary: --chromium-binary <path-to-binary>
- Custom Gecko (Firefox) binary: --gecko-binary <path-to-binary>
Chrome (system default)
npx extension@latest dev --browser=chromeEdge
npx extension@latest dev --browser=edgeCustom Chrome/Chromium path
npx extension@latest dev --chromium-binary "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"Custom Firefox path
npx extension@latest dev --gecko-binary "/Applications/Firefox.app/Contents/MacOS/firefox"<div align="center">
| <img alt="Chrome" src="https://media.extension.land/logos/browsers/chrome.svg" width="70"> | <img alt="Edge" src="https://media.extension.land/logos/browsers/edge.svg" width="70"> | <img alt="Firefox" src="https://media.extension.land/logos/browsers/firefox.svg" width="70"> | <img alt="Safari" src="https://media.extension.land/logos/browsers/safari.svg" width="70"> | <img alt="Chromium" src="https://media.extension.land/logos/browsers/chromium.svg" width="70"> | <img alt="Gecko" src="https://media.extension.land/logos/browsers/firefox.svg" width="70"> |
| :-: | :-: | :-: | :-: | :-: | :-: |
| Google Chrome<br>✅ Supported | Microsoft Edge<br>✅ Supported | Mozilla Firefox<br>✅ Supported | Apple Safari<br>✅ Supported | Chromium-based<br>✅ Supported | Gecko-based<br>✅ Supported |
</div>
Ship to the store
Build a production-ready bundle and zip it for submission to the Chrome Web Store, Edge Add-ons, or Firefox AMO:
Production build
npx extension@latest buildProduction build packaged as a ZIP
npx extension@latest build --zipPer-browser builds
npx extension@latest build --browser=firefox --zipUseful flags:
- --zip packages the build into a ZIP ready for store upload
- --zip-source includes source files for store source-code review
- --zip-filename <name> controls the output filename
- --polyfill enables the cross-browser webextension polyfill
Manage browser binaries
Skip the system-install dance. Extension.js can download and manage isolated browser binaries for clean dev sessions:
Install a managed Firefox build
npx extension@latest install firefoxInstall Chrome and Edge in one go
npx extension@latest install --browser=allPrint where managed browsers live
npx extension@latest install --whereAdd to an existing extension
Install Extension.js as a dev dependency and wire up your scripts.
npm install extension@latest --save-dev{
"scripts": {
"build": "extension build",
"dev": "extension dev",
"preview": "extension preview"
}
}Run npm run dev to develop, npm run build for production, and npm run preview to inspect the production output. See it in action.
Start from a Chrome sample
Pull any sample from Chrome Extension Samples and run it directly:
npx extension@latest dev https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/sample.page-redder --browser=edgePackage managers
<div align="center">
| <img alt="npm" src="https://media.extension.land/logos/package-managers/npm.svg" width="70"> | <img alt="pnpm" src="https://media.extension.land/logos/package-managers/pnpm.svg" width="70"> | <img alt="Yarn" src="https://media.extension.land/logos/package-managers/yarn.svg" width="70"> | <img alt="Bun" src="https://media.extension.land/logos/package-managers/bun.svg" width="70"> | <picture><source media="(prefers-color-scheme: dark)" srcset="https://media.extension.land/logos/package-managers/deno-dark.svg"><img alt="Deno" src="https://media.extension.land/logos/package-managers/deno.svg" width="70"></picture> |
| :-: | :-: | :-: | :-: | :-: |
| npm<br>✅ Supported | pnpm<br>✅ Supported | Yarn<br>✅ Supported | Bun<br>✅ Supported | Deno<br>✅ Supported |
</div>
Community
- Star the repo if Extension.js helped you ship faster
- Join the Discord for help and feedback
- Open issues and feature requests on GitHub
- Browse production-ready examples
License
MIT (c) Cezar Augusto and the Extension.js authors.
---