Add a service plugin extension to your new Wix CLI project as part of migrating an app from the legacy Wix CLI.
All service plugins follow the same pattern. The <type>/ folder level is removed in the new structure, and the files take the plugin's name:
| Legacy path | New path |
|---|---|
src/backend/service-plugins/<type>/<plugin-name>/plugin.ts | src/extensions/backend/service-plugins/<plugin-name>/<plugin-name>.ts |
src/backend/service-plugins/<type>/<plugin-name>/plugin.json | src/extensions/backend/service-plugins/<plugin-name>/<plugin-name>.extension.ts |
Note: <plugin-name> is your plugin's folder name in the legacy project. The new folder and files use the same name.
Because the folder is named after the plugin rather than its type, an app with more than one plugin of the same type keeps them in separate folders, just as it did before.
In the new project:
src/extensions/backend/service-plugins/<plugin-name>/.src/backend/service-plugins/<type>/<plugin-name>/ folder, copy plugin.ts into the new folder, and rename it to <plugin-name>.ts.Don't copy the legacy plugin.json file. You recreate its values in <plugin-name>.extension.ts.
In <plugin-name>.ts:
@wix/ecom for the Ecom types, @wix/bookings for the Bookings types, and @wix/realtime for the realtime permissions provider.In the new project:
In src/extensions/backend/service-plugins/<plugin-name>/, create <plugin-name>.extension.ts.
Add the following code, and set each field to the value the table below specifies. Replace <builderName> with the builder for your extension's legacy type, which is the extensions function that defines this kind of extension. Builder names and fields lists the builder for each type.
| Field | Source in legacy project | What to specify |
|---|---|---|
id | id in plugin.json | Copy source as is |
name | name in plugin.json | Copy source as is |
source | None | Path to <plugin-name>.ts, relative to src/ |
If your legacy plugin.json sets additional fields for the extension's type, add them inside the same object. Builder names and fields lists the additional fields each type takes, and Example with optional fields shows where they go. For example, an Ecom validations plugin takes validateInCart, and omitting it stops the plugin from validating the cart.
Important:
The id must match the value from the legacy plugin.json. Otherwise, the new entry is treated as a separate extension instead of a continuation of the legacy one.
| Legacy type | Builder | Additional fields |
|---|---|---|
ecom-shipping-rates | ecomShippingRates | Optional: description, fallbackDefinitionMandatory, learnMoreUrl, dashboardUrl, thumbnailUrl |
gift-cards-provider | ecomGiftCards | None |
ecom-discounts-trigger | ecomDiscountTriggers | None |
ecom-payment-settings | ecomPaymentSettings | Optional: fallbackValueForRequires3dSecure |
ecom-validations | ecomValidations | Optional: validateInCart |
ecom-additional-fees | ecomAdditionalFees | None |
staff-sorting-provider | bookingsStaffSortingProvider | Required: methodName, methodDescription. Optional: dashboardPluginId |
bookings-pricing-provider | bookingsPricingProvider | Optional: pricingProviderName |
realtime-permissions-provider | realtimePermissionsProvider | Optional: providerName |
Note: Four legacy service plugin types have no builder in either structure: ecom-recommendations-provider, seo-keywords-suggestions, premium-custom-charges, and external-database-provider. The legacy CLI doesn't generate them, so a project has one only if an earlier version of the legacy CLI generated it. If yours does, check with Wix before migrating it, since the new structure has nothing to migrate it to.
In the new project, in src/extensions.ts:
Import the extension:
Add a .use() call for it to the app() chain, on its own line:
Return to Install the extension's dependencies in the main migration guide.
Last updated: 10 November 2026