Migrate to WXT 
If you have problems migrating to WXT, feel free to ask for help in GitHub by starting a discussion or in Discord!
Overview 
Always start by generating a new vanilla project and merging it into your project one file at a time.
cd path/to/your/project
pnpm dlx wxt@latest init example-wxt --template vanillaIn general, you'll need to:
  Install wxt
   Extend .wxt/tsconfig.json in your project's tsconfig.json
   Update/create package.json scripts to use wxt (don't forget about postinstall)
   Move entrypoints into entrypoints/ directory
   Move assets into either the assets/ or public/ directories
   Move manifest.json content into wxt.config.ts
   Convert custom import syntax to be compatible with Vite
   Add a default export to JS entrypoints (defineBackground, defineContentScript, or defineUnlistedScript)
   Use the browser global instead of chrome
   ⚠️ Compare final manifest.json files, making sure permissions and host permissions are unchanged
WARNING
If your extension is already live on the Chrome Web Store, use Google's update testing tool to make sure no new permissions are being requested.
Every project is different, so there's no one-solution-fits-all to migrating your project. Just make sure wxt dev runs, wxt build results in a working extension, and the list of permissions in the manifest.json hasn't changed. If all that looks good, you've finished migrating your extension!
Popular Tools/Frameworks 
Here's specific steps for other popular frameworks/build tools.
Plasmo 
- Install 
wxt - Move entrypoints into 
entrypoints/directory- For JS entrypoints, merge the named exports used to configure your JS entrypoints into WXT's default export
 - For HTML entrypoints, you cannot use JSX/Vue/Svelte files directly, you need to create an HTML file and manually create and mount your app. Refer to the React, Vue, and Svelte templates as an example.
 
 - Move public 
assets/*into thepublic/directory - If you use CSUI, migrate to WXT's 
createContentScriptUi - Convert Plasmo's custom import resolutions to Vite's
 - If importing remote code via a URL, add a 
url:prefix so it works with WXT - Replace your Plasmo tags (
--tag) with WXT build modes (--mode) - ⚠️ Compare the old production manifest to 
.output/*/manifest.json. They should have the same content as before. If not, tweak your entrypoints and config until they are the same. 
CRXJS 
If you used CRXJS's vite plugin, it's a simple refactor! The main difference between CRXJS and WXT is how the tools decide which entrypoints to build. CRXJS looks at your manifest (and vite config for "unlisted" entries), while WXT looks at files in the entrypoints directory.
To migrate:
- Move all entrypoints into the 
entrypointsdirectory, refactoring to WXT's style (TS files have a default export). - Move entrypoint specific options out of the manifest and into the entrypoint files themselves (like content script 
matchesorrun_at). - Move any other 
manifest.jsonoptions into thewxt.config.tsfile, like permissions. - For simplicity, you'll probably want to disable auto-imports at first (unless you were already using them via 
unimportorunplugin-auto-imports). If you like the feature, you can enable it later once you've finished the migration. - Update your 
package.jsonto include all of WXT's suggested scripts (see step 4) - Specifically, make sure you add the 
"postinstall": "wxt prepare"script to yourpackage.json. - Delete your 
vite.config.tsfile. Move any plugins into thewxt.config.tsfile. If you use a frontend framework, install the relevant WXT module. - Update your typescript project. Extend WXT's generated config, and add any path aliases to your 
wxt.config.tsfile. - ⚠️ Compare the old production manifest to 
.output/*/manifest.json. They should have the same content as before. If not, tweak your entrypoints and config until they are the same. 
Here's an example migration: GitHub Better Line Counts - CRXJS → WXT
vite-plugin-web-extension 
Since you're already using Vite, it's a simple refactor.
- Install 
wxt - Move and refactor your entrypoints to WXT's style (with a default export)
 - Update package.json scripts to use 
wxt - Add 
"postinstall": "wxt prepare"script - Move the 
manifest.jsonintowxt.config.ts - Move any custom settings from 
vite.config.tsintowxt.config.ts's - ⚠️ Compare the old production manifest to 
.output/*/manifest.json. They should have the same content as before. If not, tweak your entrypoints and config until they are the same.