Upgrade to frontend builder v2 for the Back Office
Edit on GitHubThis document provides instructions for moving a project from the @spryker/oryx-for-zed npm package — builder v1 — to builder v2, which ships inside the Gui module.
For an overview of the builder, see Frontend builder for the Back Office v2.
Estimated migration time: 1h
Prerequisites
- Node.js 24.15.0 or later, npm 10 or later.
spryker/gui5.8.0 or later, together with the Back Office modules that allow it.
1) Update composer packages
Gui 5.8.0 ships the builder and the npm dependency set of the Back Office, and the Back Office modules released with it widen their spryker/gui constraint to allow it — see Back Office modules released with builder v2. Update Gui together with the modules that depend on it:
composer require spryker/gui:"^5.8.0" --no-update
composer update spryker/gui "spryker/*" "spryker-feature/*" --with-dependencies
Updating spryker/gui on its own fails or leaves the project in a broken state: the locked Back Office modules constrain Gui to an older minor, and composer does not update packages that are not listed in the update command.
The Back Office modules released with builder v2 keep the entry point files and names the legacy builder relies on, so after this step the project still builds with @spryker/oryx-for-zed. You can ship the package update first and switch to builder v2 in a follow-up — the intermediate state builds and runs.
2) Update Node.js and npm versions
- In all
deploy.*.ymlfiles used by the frontend, set the versions:
image:
...
node:
version: 24
npm: 10
- If the project has an
.nvmrcfile, update it:
24
3) Update package.json
- Update the engines:
"engines": {
"node": ">=24.15.0",
"npm": ">=10.0.0"
}
- Declare the
assets/Zeddirectory of the Gui module as an npm workspace, so that npm installs the builder’s dependencies:
"workspaces": [
"vendor/spryker/gui/assets/Zed"
]
For what this does and how it changes the commands, see npm workspaces for the frontend builders.
- Replace the
zed:*scripts so they delegate to thespryker-zed-guiworkspace, add the lint scripts, and add the configuration generation topostinstall:
"scripts": {
"zed": "npm run build -w spryker-zed-gui --",
"zed:watch": "npm run build:watch -w spryker-zed-gui --",
"zed:production": "npm run build:production -w spryker-zed-gui --",
"zed:lint": "npm run lint -w spryker-zed-gui --",
"zed:stylelint": "npm run stylelint -w spryker-zed-gui --",
"postinstall": "npm run update:config -w spryker-zed-gui"
}
If postinstall already runs the configuration generation of another builder, chain them:
"postinstall": "npm run update:config -w mp-zed-ui && npm run update:config -w spryker-zed-gui"
- Remove the legacy builder:
"@spryker/oryx-for-zed": "~3.6.1"
- Remove the Back Office build dependencies the project declared for the legacy builder. Gui declares the whole toolchain in
vendor/spryker/gui/assets/Zed/package.jsonand has no peer dependencies, so a copy in the project pins a second version of the same package. Everything below is installed automatically through thespryker-zed-guiworkspace and goes from yourpackage.json:
- Toolchain:
@babel/core,@babel/plugin-transform-class-properties,@babel/plugin-transform-runtime,@babel/preset-env,@babel/preset-typescript,@babel/runtime,@jest/globals,@types/jquery,@types/node,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,autoprefixer,babel-loader,chokidar,commander,copy-webpack-plugin,css-loader,css-minimizer-webpack-plugin,eslint,fast-glob,imports-loader,jest,jest-environment-jsdom,mini-css-extract-plugin,postcss,postcss-loader,postcss-selector-parser,resolve-url-loader,sass-embedded,sass-loader,stylelint,stylelint-config-standard-scss,terser-webpack-plugin,ts-jest,typescript,webpack,webpack-merge. - Runtime libraries of the Back Office:
@fortawesome/fontawesome-free,@popperjs/core,@spryker/nestable,autonumeric,bootstrap,codemirror,datatables.netand its-bs5,-buttons,-buttons-bs5,-responsive,-responsive-bs5,-select,-select-bs5packages,dompurify,flatpickr,highlight.js,jquery,jquery-migrate,jquery-ui,jstree,marked,pace,select2,summernote,sweetalert2.
Keep a package only if another builder in the project still declares it as a peer dependency. See What you can remove from your package.json.
4) Delete the project build script
If the project extended the legacy builder as described in Overriding Webpack, JS, SCSS for ZED on the project level, delete frontend/zed/build.js and any webpack configuration next to it. Each thing it did has a replacement:
In frontend/zed/build.js |
In builder v2 |
|---|---|
entry.dirs with src/Pyz/Zed, so that project entry points are found |
nothing — src/Pyz/Zed is scanned by default |
resolveModules.dirs, so that project npm packages resolve |
nothing — every assets/Zed/node_modules directory in the scanned roots is added to the resolution |
resolve.alias entries for core modules |
nothing — a @zed/<module>/* alias is generated per module; a hand-written alias goes into compilerOptions.paths of a tsconfig.zed.json kept in the project root, which the generation reconciles in place |
| any other webpack customization | frontend/backoffice.settings.mts — see Project-level builder settings |
The builder has no webpack configuration hook: the settings file overrides the source roots, the output directories, and the type checking switch, and everything else is fixed.
The migration is the steps in this document. Gui ships no project migration tool, and nothing in the module rewrites the project tree for you — apart from the configuration generation described in the next step.
5) Generate the configuration
Run the generation:
npm run update:config -w spryker-zed-gui
It writes tsconfig.defaults.json, tsconfig.zed.json, and tsconfig.zed.lint.json into the builder directory, and creates the project root tsconfig.json as a solution file if the project has none. A root tsconfig.json that is a complete configuration of your own is left unchanged; its compilerOptions override the builder defaults. For the full ownership split, see Generated configuration.
postinstall runs the same command, so a plain npm install keeps the configuration current afterwards. The generated files are gitignored in the Gui module and regenerated on every install, so there is nothing to commit.
6) Fix Sass deprecations in project stylesheets
The legacy builder logged Sass deprecation warnings; builder v2 fails the build on a warning in a stylesheet the project owns. Run a build and fix what it reports:
@import 'partial'of your own partial becomes@use 'partial'.@import '~package/file.css'becomes@use 'package/file.css' as *, or arequire('package/file.css')in the entry point.- A global color function becomes its
sass:colorequivalent:darken($color, 8%)becomescolor.adjust($color, $lightness: -8%)after@use 'sass:color'.
Warnings from installed packages and from the Inspinia theme do not fail the build; they are printed as one summary line. See Stylesheets.
7) Install and build
npm install
npm run zed
Then verify the rest of the toolchain:
npm run zed:lint
npm run zed:stylelint
In a project, both cover src/Pyz/Zed only: the core modules arrive in vendor/ and are not the project’s to report on. zed:lint reports that type checking is off — it is off by default in a project, see TypeScript.
Finally, check the Back Office in the browser. Every entry point still produces js/<name>.js and css/<name>.css under the same names, so the templates need no change. The only new files are the hashed chunks under js/chunks/ and css/chunks/.
Back Office modules released with builder v2
The Back Office modules were released together with the builder — spryker/gui as a minor version, all the others as patch versions that allow Gui 5.8 in their constraints. The update command in step 1 picks them up automatically.
The patch releases change no behavior of their own: the entry point files keep their names, so the modules still build with the legacy builder as well. Some of them additionally carry lint fixes and the @use conversion of their stylesheets, which is what removes the Sass deprecation warnings from the core modules under builder v2.
Module versions released with builder v2
| Module | Version |
|---|---|
spryker-feature/order-experience-management |
^2.1.1 |
spryker-feature/product-experience-management |
^4.1.2 |
spryker-feature/purchasing-control |
^1.4.1 |
spryker-feature/self-service-portal |
^20.17.2 |
spryker/acl |
^3.28.1 |
spryker/agent-gui |
^2.1.1 |
spryker/ai-foundation |
^0.9.1 |
spryker/analytics-gui |
^1.2.1 |
spryker/api-key-gui |
^2.3.1 |
spryker/app-catalog-gui |
^1.4.3 |
spryker/availability-gui |
^7.3.1 |
spryker/category-gui |
^2.9.1 |
spryker/category-image-gui |
^1.10.1 |
spryker/cms |
^7.22.1 |
spryker/cms-block-category-connector |
^2.12.1 |
spryker/cms-block-gui |
^2.18.1 |
spryker/cms-block-product-connector |
^1.8.1 |
spryker/cms-content-widget |
^1.13.1 |
spryker/cms-gui |
^5.21.1 |
spryker/cms-slot-block-gui |
^1.7.1 |
spryker/cms-slot-block-product-category-gui |
^1.4.1 |
spryker/cms-slot-gui |
^1.5.1 |
spryker/collector |
^6.13.1 |
spryker/comment-gui |
^1.2.1 |
spryker/comment-sales-connector |
^1.5.2 |
spryker/company-business-unit-gui |
^2.16.1 |
spryker/company-gui |
^1.10.1 |
spryker/company-role-gui |
^1.13.1 |
spryker/company-supplier-gui |
^1.6.1 |
spryker/company-unit-address-gui |
^1.7.1 |
spryker/company-unit-address-label |
^1.6.1 |
spryker/company-user-gui |
^1.16.1 |
spryker/configurable-bundle-gui |
^2.2.1 |
spryker/configuration |
^1.4.1 |
spryker/content-file-gui |
^2.5.1 |
spryker/content-gui |
^3.2.1 |
spryker/content-navigation-gui |
^1.2.1 |
spryker/content-product-gui |
^1.7.1 |
spryker/content-product-set-gui |
^1.6.1 |
spryker/country |
^4.9.1 |
spryker/country-gui |
^1.3.1 |
spryker/currency-gui |
^1.3.1 |
spryker/customer |
^7.87.2 |
spryker/customer-group |
^2.14.1 |
spryker/customer-note-gui |
^1.4.1 |
spryker/customer-user-connector-gui |
^2.2.1 |
spryker/dashboard |
^1.4.1 |
spryker/data-import-merchant-portal-gui |
^2.4.1 |
spryker/dataset |
^1.8.1 |
spryker/development |
^3.55.1 |
spryker/discount |
^9.56.1 |
spryker/discount-promotion |
^4.16.1 |
spryker/dynamic-entity-gui |
^1.6.2 |
spryker/falcon-ui |
^0.1.3 |
spryker/file-manager-gui |
^3.2.1 |
spryker/gift-card-balance |
^1.7.1 |
spryker/glossary |
^3.22.2 |
spryker/gui |
^5.8.0 |
spryker/locale-gui |
^2.2.1 |
spryker/manual-order-entry-gui |
^0.9.9 |
spryker/merchant-agent-gui |
^2.1.1 |
spryker/merchant-commission-gui |
^2.1.1 |
spryker/merchant-gui |
^4.2.1 |
spryker/merchant-product-offer-gui |
^2.1.1 |
spryker/merchant-profile-gui |
^1.5.1 |
spryker/merchant-profile-merchant-portal-gui |
^4.4.1 |
spryker/merchant-registration-request |
^1.3.1 |
spryker/merchant-relation-request-gui |
^2.1.1 |
spryker/merchant-relationship-gui |
^1.14.1 |
spryker/merchant-relationship-product-list-gui |
^2.5.1 |
spryker/merchant-relationship-sales-order-threshold-gui |
^1.11.2 |
spryker/merchant-sales-order-merchant-user-gui |
^2.3.1 |
spryker/merchant-sales-return-merchant-user-gui |
^2.2.1 |
spryker/merchant-stock-gui |
^1.2.1 |
spryker/merchant-user-gui |
^1.8.1 |
spryker/money-gui |
^1.4.1 |
spryker/multi-factor-auth |
^2.8.1 |
spryker/navigation-gui |
^3.5.1 |
spryker/oms |
^11.54.6 |
spryker/order-custom-reference-gui |
^1.2.1 |
spryker/payment-gui |
^2.1.1 |
spryker/price-product-merchant-relationship-gui |
^1.5.1 |
spryker/price-product-merchant-relationship-merchant-portal-gui |
^3.1.1 |
spryker/price-product-offer-gui |
^2.1.1 |
spryker/price-product-schedule-gui |
^3.5.1 |
spryker/price-product-volume-gui |
^3.6.1 |
spryker/product-alternative-gui |
^2.1.1 |
spryker/product-approval-gui |
^2.1.2 |
spryker/product-attribute-gui |
^2.5.1 |
spryker/product-barcode-gui |
^1.5.1 |
spryker/product-category |
^4.36.1 |
spryker/product-category-filter-gui |
^3.2.1 |
spryker/product-label-gui |
^4.4.1 |
spryker/product-list-gui |
^3.2.1 |
spryker/product-management |
^0.20.20 |
spryker/product-measurement-unit-gui |
^1.2.1 |
spryker/product-merchant-portal-gui |
^5.5.1 |
spryker/product-offer-gui |
^2.2.1 |
spryker/product-offer-service-point |
^1.3.1 |
spryker/product-offer-service-point-gui |
^2.1.1 |
spryker/product-offer-shipment-type-gui |
^2.1.1 |
spryker/product-offer-validity-gui |
^2.1.1 |
spryker/product-option |
^8.29.1 |
spryker/product-relation-gui |
^2.2.1 |
spryker/product-review-gui |
^1.9.1 |
spryker/product-search |
^5.29.1 |
spryker/product-set-gui |
^3.3.1 |
spryker/queue |
^1.30.1 |
spryker/refund |
^5.16.2 |
spryker/sales |
^11.85.2 |
spryker/sales-order-threshold-gui |
^2.2.2 |
spryker/sales-reclamation-gui |
^2.2.1 |
spryker/sales-return-gui |
^2.3.2 |
spryker/sales-service-point-gui |
^1.2.1 |
spryker/search |
^8.29.2 |
spryker/search-elasticsearch-gui |
^2.1.1 |
spryker/security-gui |
^2.10.1 |
spryker/service-point |
^1.3.1 |
spryker/shipment |
^8.28.2 |
spryker/shipment-gui |
^3.5.1 |
spryker/state-machine |
^2.27.2 |
spryker/state-machine-visualizer |
^0.1.3 |
spryker/stock-gui |
^3.1.1 |
spryker/storage |
^3.25.2 |
spryker/storage-gui |
^2.1.1 |
spryker/store |
^1.41.1 |
spryker/store-context-gui |
^2.2.1 |
spryker/store-gui |
^2.1.3 |
spryker/symfony-scheduler |
^1.4.1 |
spryker/tax |
^5.21.1 |
spryker/user |
^3.35.1 |
spryker/user-locale-gui |
^1.3.1 |
spryker/user-merchant-portal-gui |
^4.4.2 |
spryker/warehouse-user-gui |
^2.2.1 |
spryker/workflow |
^0.3.1 |
Behavior changes
- Code loaded on demand is no longer in the shared bundle. The legacy builder merged every library loaded with
import()intospryker-zed-gui-commons.js, so it was present on every page whether the page needed it or not. Builder v2 emits such code as separate chunks fetched on first use. Project code that relied on one of these libraries being available synchronously on every page has to import it explicitly. animate.cssandmetismenuare gone from the Gui runtime dependencies; nothing in the Back Office imported them. If your project does, declare them in your ownpackage.json.- Runtime libraries moved to newer versions: jQuery 3.7, jQuery Migrate 3.6, Select2 4.1, AutoNumeric 4.10, and marked 18. Select2 4.1 changes its generated markup — the clear button of a select with
allowClearis a<button class="select2-selection__clear">element — so end-to-end tests that select buttons inside a Select2 container may need narrower selectors. - Sass deprecations in project stylesheets fail the build — see step 6.
Post-upgrade notes
- Live reload.
npm run zed:watchnow reloads the open Back Office page after a.js,.ts,.scss, or.twigchange; a CSS-only change is applied without a reload. No extra setup is needed. SetSPRYKER_FRONTEND_RELOAD=0to turn it off. A Twig change shows up after the reload only whenApplicationConstants::ENABLE_APPLICATION_DEBUGis on, which is the default in a Docker SDK development environment; otherwise rundocker/sdk console twig:cache:warmer— see Live reload. - TypeScript. Back Office modules can ship
.entry.tsand.tsfiles. To type-check the project’s own TypeScript, settypecheck: trueinfrontend/backoffice.settings.mts. - Lint scope.
npm run zed:lintandnpm run zed:stylelintreport onsrc/Pyz/Zedonly. Project-level lint configuration lives at the project root:eslint.config.backoffice.mjsandstylelint.config.backoffice.mjs. Without them, the configurations shipped in Gui are used. - A core module added to or removed from the project changes the generated
@zed/*aliases andincludeglobs.postinstallregenerates them on the nextnpm install.
Thank you!
For submitting the form