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.
- 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.
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.
