The frameworks
Two structural differences matter more than any feature row:
- Where the manifest lives. Extension.js reads your
manifest.jsonand compiles whatever it declares. WXT and Plasmo generate the manifest from file conventions and config. CRXJS reads a manifest but resolves it through Vite’s plugin API, which is why bundler upgrades can break it (see the Vite 8 fileName error). - Who owns the bundler. A framework that wraps a general-purpose bundler inherits that bundler’s breaking changes. Extension.js treats the bundler as an internal detail: you never configure it, and upgrades are the framework’s problem, not yours.
Detailed comparisons and migrations
- Extension.js vs WXT: the closest comparison, dimension by dimension.
- Extension.js vs Plasmo: manifest model, dev loop, packaging, and maintenance status with dates.
- Migrate from CRXJS: step-by-step, about ten minutes for a typical project.
- Fix: Content script fileName is undefined: the CRXJS + Vite 8 build error, with workarounds.
- Migrate from Plasmo: convention-to-manifest mapping, env vars, and CSUI.
- Migrate a webpack or Vite extension: entries to manifest.json, loaders and plugins, and the traps that cost real migrations time.
Try it without committing
Run any extension template, or any extension repository on GitHub, with one command:chrome.* calls, and styling carry over from any of these frameworks. The migration guides cover the wiring that changes.
