Migrate an app from the legacy Wix CLI for Apps to the new Wix CLI. The two CLIs use different project structures and toolchains. The migration moves your app's code into a project with the new Wix CLI project structure, so that you can develop the app with the commands, generators, and supported extensions of the new Wix CLI.
The migration creates a new Wix CLI project for the same app, with the same project ID. Both projects share a single version history. You move your backend and every extension into the new project, test the project on a development site, and release it in one version. Once you've confirmed that the new version of your app works, you delete the legacy project.
Note: The Legacy Wix CLI for Apps reaches its end of life on February 28, 2027. After that date, you can't release new versions of apps built with it, so migrate before then to keep releasing your app.
The new Wix CLI requires Node.js 24.22.1 or later. If your legacy project pins an older version, for example in an .nvmrc file, switch to a supported version before you run the commands in this guide.
To create a project that has the same app ID and project ID as your legacy project:
In the terminal, navigate to the folder where you want to create the new project.
Run the following command:
If prompted to install the package, confirm it.
Select Add new extensions for an existing Wix app.
From the list, select the Wix CLI app you want to migrate. If several of your apps have similar names, confirm the selection after the project is created, as described below.
Enter a name for the project folder. The CLI generates the new project and shows a Results summary when it's done.
In the new project's wix.config.mjs, set projectId to the projectId value in your legacy project's wix.config.json. The CLI sets it to the folder name, inside the customExtensions() call:
Important:
The new project must have the same appId and projectId as your legacy project. The CLI sets appId to the app you selected. To confirm that you selected the right app, compare the appId value in wix.config.mjs with the one in your legacy project's wix.config.json.
The new project comes with a default my-page dashboard page extension that isn't part of your app. To keep it out of the migrated app:
Delete the src/extensions/dashboard/pages/my-page/ folder.
In src/extensions.ts, remove the myPage import and the .use(myPage) call. The CLI generates the file as follows:
After the change, the file contains the following:
If your legacy project has web methods or HTTP functions, migrate them to the new project before migrating extensions. Extensions may reference backend code, so migrating the backend first keeps your extension migrations working.
Complete each of the following that applies to your project:
If your project uses web methods, follow the Migrate from Web Methods to HTTP Endpoints guide.
If your project uses HTTP functions, follow the Migrate from HTTP Functions to HTTP Endpoints guide.
If you keep your endpoints in a folder other than src/api/, name that folder in the apiDir option of app() in src/extensions.ts:
Endpoints are discovered only in that folder. apiDir defaults to api, so a project that keeps its endpoints in src/api/, as the two backend guides do, needs no declaration.
Copy any shared code outside src/backend/ that your backend imports, such as src/consts.ts, src/types.ts, or a src/utils/ folder, into the new project at the same path. The new project structure reserves no folder for shared code, so the files keep their paths. Update the import paths in the moved backend files as needed.
Install any packages your backend code imports that the new project doesn't already have, the same way you do for an extension in Install the extension's dependencies.
For each extension in your legacy project, add the extension to the new project, install its dependencies, and build the project. Repeat until all your extensions are in the new project.
Important: Don't release until all your extensions are in the new project. The new project has the same project ID as your legacy project, so a release from it contains only the extensions that are in it.
In the new project, add the extension by following the migration guide for your extension type.
If the extension calls web methods or HTTP functions, also update those call sites. See Migrate from Web Methods to HTTP Endpoints or Migrate from HTTP Functions to HTTP Endpoints.
If the extension imports code that isn't part of any extension, such as components, hooks, or helpers under src/dashboard/, copy that code into the new project at the same path, and update the relative imports from the extension's new location. The new project structure reserves no folder for shared code, so the files keep their paths.
As you migrate extensions, src/extensions.ts accumulates one import per extension and one chained .use() call per extension. For example, after migrating three extensions:
Install each package that the extension's code imports, at the version range in your legacy project's package.json:
The new project starts with a small set of dependencies, so packages that your legacy project used, such as @wix/stores or @wix/crm, aren't installed in it. Without a version range, npm install takes the latest version, which can be a newer major version than your code was written for.
Typecheck the project:
Note: The typecheck resolves module imports, so it reports a package that isn't installed as Cannot find module '<package>' against the file that imports it. This error is clearer than the build error for the same cause.
After the typecheck passes, build the project to confirm that the extension compiles:
The typecheck reports missing packages and type errors, and the build also produces the bundle and the app manifest.
If the first build after you install a package fails with a pre-bundle error, see Troubleshooting.
You can also check each extension on a development site as you go, the same way Test the project describes for the whole project.
The following table lists the migration guide for each extension type:
| Extension type | Migrate |
|---|---|
| Dashboard page | Migrate a Dashboard Page Extension |
| Dashboard modal | Migrate a Dashboard Modal Extension |
| Dashboard plugin | Migrate a Dashboard Plugin Extension |
| Dashboard menu plugin | Migrate a Dashboard Menu Plugin Extension |
| Custom element | Migrate a Custom Element Extension |
| Site plugin | Migrate a Site Plugin Extension |
| Embedded script | Migrate an Embedded Script Extension |
| Service plugin | Migrate a Service Plugin Extension |
| Event | Migrate an Event Extension |
Once all your extensions are in the new project, test the project, release it, and check the new version on a site. Delete the legacy project only after the new version of your app works.
You test the project on a development site, where your app is installed and your extensions run as they do for Wix users. The project uses one development site at a time and keeps using it until you change it.
Choose the site based on whether your app already works on one:
The new project starts with no development site. Set the site you chose based on how you run the CLI:
When the site is set for the project:
If the development session isn't running, run wix app dev from the new project.
Open your site, editor, or dashboard from the links the session prints, and check that each extension works as it did before the migration. For where to check each extension type, see the documentation of that type in About App Extensions in the Wix CLI.
If an extension also fails in the legacy project, handle the failure separately from the migration. The migration keeps the behavior of each extension and doesn't fix it.
If an AI agent runs the migration, have it report such failures instead of changing the extension's code to make them go away.
Warning: A released version of your app can hide a broken migration. Where Wix serves your app rather than your dev session, you see the released version instead of your local code, and the extension looks correct while your migrated code never runs. Two cases to watch:
Open every extension from the running dev session, and treat a service plugin as verified only after you release.
When every extension works on your development site, release the project as a single version of your app.
Warning: A wix app release can't be undone. A broken release stays broken for Wix users whose sites received it until you release a fix. Verifying on a development site beforehand catches most issues.
For details on how Wix users receive new versions, see About App Versioning.
Build the project:
Preview the project, install the preview on your development site from one of the links the CLI prints, and check your extensions there:
The preview runs the build you just made. A site keeps the preview it was installed with, so after each wix app preview, install the new preview from its link.
Choose a minor version. Your app keeps the same extensions and permissions, so the release doesn't need users to accept an update.
On a site where your app is installed, check the release as follows:
Once the new version of your app works on your site, delete the legacy project.
Warning: If you release from the legacy project, which has the same project ID as the new project, the new version of your app contains only what's in the legacy project. Your migrated extensions return to their legacy versions, and anything you added in the new project, such as new extensions, is removed. This applies to any release from the legacy project, however long after the migration.
The following problems can occur when you install, build, or release the new project.
If npm install fails with ERESOLVE peer-dependency conflicts, allow legacy peer dependencies and reset the install:
At the top of your project's folder, create a .npmrc file containing legacy-peer-deps=true.
In the terminal, navigate to your project's folder and run the following command:
If wix app build fails with There is a new version of the pre-bundle for "<path>" on the first build after you install a package, run the command again. The second build passes.
If an extension doesn't appear where you expect it after you release, the most likely cause is a value from its legacy configuration that wasn't carried over to the new project. This applies wherever the extension surfaces, not only the dashboard.
The build needs the WIX_CLIENT_ID environment variable. If it isn't set, the build fails.
Set it in one of these ways:
.env.local file containing WIX_CLIENT_ID=<your-app-id>.wix app env pull.Last updated: 11 November 2026