Highlights
Vendure Core v3.7 focuses on developer experience, dashboard extensibility, and security hardening. It adds first-class CLI commands for running and building a project, a doctor diagnostic command, AI-assisted project scaffolding, an opt-in pre-bundled dashboard, new dashboard extension points, a round of supply-chain and dependency hardening, disclosed fixes for several reported vulnerabilities, and two new pluggable strategies.
It's a minor release, so a handful of changes need your attention before upgrading — see Breaking Changes at the bottom.
Developer Experience
CLI lifecycle commands
Three new commands run a Vendure project without hand-rolled ts-node / concurrently scripts (#4774):
vendure dev— server, worker, and dashboard with auto-reload (backend files,.env, dashboard extensions; Node inspector flags supported).--no-reloadto disable watching.vendure build— compiles server, worker, and dashboard for production (tsconfig discovery, separate worker tsconfig,--clean,--watch,--verbose).vendure start— runs the compiled server and worker with prefixed output and coordinated shutdown.
The add, migrate, schema, and codemod commands now fail fast in non-interactive environments (CI, AI agents) instead of hanging on a prompt.
vendure doctor
A new diagnostic command that runs checks against a project and reports pass / warn / fail / skip (#4777). Five checks by default — Project, Dependencies, Config, Schema, Database — plus a Production profile via --profile production. Supports --check, --format json, and --strict for CI use.
AI-assisted development & more package managers
- Vendure skills for AI agents: run
npx skills add vendurehq/vendure - New projects from
@vendure/createnow include anAGENTS.mdcontext file for AI coding agents (#4850). @vendure/createnow supports bun, pnpm, and yarn in addition to npm (#4877).
Pre-bundled dashboard (experimental, opt-in)
Set useExperimentalBundle: true on vendureDashboardPlugin to ship the dashboard as a pre-built ESM bundle instead of thousands of source modules (#4719). Measured on a fresh project with one extension, cold-loading /dashboard/:
| Metric | Source mode (default) | Bundle mode | Change |
|---|---|---|---|
| Network requests | 3,047 | 39 | −98.7% |
| DOMContentLoaded | 897 ms | ~370 ms | −59% |
| JS heap used | 168 MB | ~95 MB | −43% |
The default is unchanged; this is opt-in and experimental while we test it in the wild.
Dashboard Improvements
- Custom React providers (#4600) — extensions can register providers rendered around the dashboard at
apporlayoutlevel, with explicit ordering, viadefineDashboardExtension(). - User stylesheets (#4765, #4905) — a new
theme.additionalStylesheetsoption onvendureDashboardPlugininjects your CSS through the dashboard's Tailwind v4 pipeline. - Configurable DataTable column defaults (#4197) — plugins can set default column visibility and order for data tables via the Plugin Extension API.
- Configurable TanStack Router options (#4862) — a new
tanstackRouterPluginOptionsoption; also fixes dashboard builds failing withEXDEV: cross-device link not permittedwhennode_modulesis on a different volume. - Focal point editor in the asset preview dialog (#4755).
- New Uzbek translation (#4837) and additional Russian order-action strings (#4838).
Security Hardening
Dependency audit
We audited Vendure's full dependency footprint (#4761), from a baseline of ~1,880 unique production packages, using four rules: remove unused, replace with Node built-ins, vendor small pure-code packages, keep security-sensitive/canonical ones. Results:
- ~145 transitive dependencies removed with no behaviour change (#4762) — dropping unused
body-parser, recategorising mislabelled@types/*/faker, and replacingnode-fetch/form-datawith nativefetch/FormData. - Curated telemetry instrumentation set (#4764) — ship the seven instrumentations that match the Vendure stack instead of 40+; opt in to the rest.
- Dropped
@nestjs/terminus(#4771), replaced its health check with a directSELECT 1. - Vendoring / native replacements for
change-case,graphql-fields,progress, andtcp-port-used(#4767, #4768, #4769, #4770).
Clearing npm audit warnings
Runtime dependencies were updated to clear npm audit warnings a fresh install reports (#4906) — most notably mjml 4 → 5 (removing the unmaintained html-minifier) and nodemailer 6 → 9, plus version-floor bumps for i18next-fs-backend and i18next-http-middleware.
npm audit |
Before (3.6.4) | After |
|---|---|---|
| Critical | 0 | 0 |
| High | 42 | 9 |
| Moderate | 6 | 5 |
| Total | 48 | 14 |
Reported vulnerabilities
Fixes for the following reported vulnerabilities are all in 3.7.0. Where the fix also landed on the 3.6.x line, it's available in the latest 3.6.x patch, so you can take the fix without upgrading to the minor.
| Severity | Vulnerability | Advisory | Fixed in |
|---|---|---|---|
| Critical | External-authentication account takeover: an external/SSO login could be linked to a pre-existing account by email without verification | GHSA-6j36-r6pr-59x4 | 3.7.0 |
| High | Stored XSS in the dashboard from unsafe HTML-stripping of entity descriptions | GHSA-xhq9-whgq-49j5 | 3.7.0 and latest 3.6.x |
| High | Unauthenticated denial of service (ReDoS) via the regex filter on SQLite backends |
GHSA-jgm3-qmp2-c4p7 | 3.7.0 and latest 3.6.x |
| High | File-upload type bypass: uploads accepted on the Content-Type header without verifying contents |
GHSA-88rq-mq4v-frmm | 3.7.0 and latest 3.6.x |
| Moderate | Shop API list queries could return non-public entities when filterOperator was OR |
GHSA-xf65-r35x-wmmv | 3.7.0 and latest 3.6.x |
Our thanks to the researchers who reported these responsibly.
Other security fixes
- Channel scoping on entity updates (#4821) —
AssetService.updateandStockLocationService.updatenow scope the lookup by channel, closing a gap where a channel-restricted administrator could modify an entity in another channel. - Refuse the default superadmin password in production (#4718) — see Breaking Changes.
New Pluggable Strategies
Both ship with a default that reproduces the existing behaviour exactly, so neither changes anything unless you opt in.
CustomerChannelAssignmentStrategy(#4863) — control whether an authenticated customer is auto-assigned to a channel they target but aren't a member of. ReturnfalsefromcanAssignCustomerToChannel()to let them use the channel for the session without becoming a member (useful for strict B2B/multi-channel separation). Configure viaauthOptions.customerChannelAssignmentStrategy.OrderLineDiscountDistributionStrategy(#4818) — control how an order-level discount is distributed across order lines. The default weights each line by its current prorated price. If you need refunds to reconcile exactly with the order total, you can now supply a strategy that weights by originally-placed quantity instead. Configure viaorderOptions.orderLineDiscountDistributionStrategy.
Other Notable Changes
CouponRemovedDuringCheckoutErroradded toAddPaymentToOrderResult(#4683) — handle a coupon becoming invalid mid-checkout.- Pooled SMTP options in the email plugin (#4861).
- Exclude draft orders from promotion usage-limit counts (#4854).
- Prevent duplicate-key errors in DefaultSearchPlugin index writes (#4809).
- Seed StockLevel on variant channel assignment (#4864).
- Prevent unbounded i18next preload growth (#4824) — memory-leak fix for long-running servers.
Breaking Changes
v3.7 is a minor release, but a few changes need your attention.
- Coupon codes are now compared case-insensitively (#4419), bringing Vendure in line with other commerce platforms. This only affects you if you've used different-case versions of the same code for distinct promotions — those will now collide.
- The default superadmin password is refused in production (#4718). If your production environment still uses the default superadmin password, Vendure will not start. Change it before upgrading.
- External authentication now requires a verified email to link to an existing account. As part of the fix for the account-takeover advisory (GHSA-6j36-r6pr-59x4), an external login is only linked to a pre-existing account when the external email is verified. If you have a custom
AuthenticationStrategy, it must setverified: trueon the returned user data for provider-verified emails, otherwise the link is refused. Creating new accounts is unchanged. - Email plugin dependency upgrades:
mjml4 → 5 andnodemailer6 → 9. If you use MJML email templates or a custom nodemailer transport configuration, review these major upgrades for behavioural changes.
Migration Guide
See the v3.7 Migration Guide for detailed, example-driven steps on each of the changes above.
What's Changed
- fix(dashboard): add entity to DetailPage by @LucidityDesign in #4369
- feat(core): Add CouponRemovedDuringCheckoutError to AddPaymentToOrderResult by @michaelbromley in #4683
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4690
- spike(dashboard): Pre-bundled dashboard with useExperimentalBundle opt-in (#4719) by @michaelbromley in #4720
- refactor(core): Vendor a focused ProgressBar helper, drop
progressdep by @michaelbromley in #4770 - refactor(create): Inline native net.Socket implementation, drop tcp-port-used by @michaelbromley in #4768
- feat(telemetry-plugin): Narrow default instrumentations to Vendure stack by @michaelbromley in #4764
- refactor(core): Drop @nestjs/terminus dependency by @michaelbromley in #4771
- refactor(core): Vendor graphql-fields helper and drop the npm dep by @michaelbromley in #4769
- refactor(cli): Vendor case-conversion helpers and drop change-case by @michaelbromley in #4767
- chore(deps): Reduce supply-chain surface area (audit branch) by @michaelbromley in #4762
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4783
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4791
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4799
- feat(cli): Add dev/build/start lifecycle commands and a distributable agent skill by @dlhck in #4774
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4802
- feat(dashboard): Add support for custom React providers in dashboard by @alingabrieldm in #4600
- fix(dashboard): use rich text editor for shipping method description by @latifniz in #4853
- feat(core): Add CustomerChannelAssignmentStrategy to control channel auto-assign by @gabriellbui in #4863
- feat(dashboard): Add Uzbek (uz) translation for the Dashboard by @IsroilovA in #4837
- fix(dashboard): Regenerate Uzbek catalog and translate job cancel toast plurals by @michaelbromley in #4871
- feat(cli): add vendure doctor command with project check by @Ryrahul in #4777
- docs: Add vendure doctor CLI command docs by @michaelbromley in #4872
- docs: Remove redundant package-manager tabs from Admin UI guide by @michaelbromley in #4873
- feat(dashboard): Focal point editor in shared asset preview dialog by @grolmus in #4755
- docs(core): document verified-email contract for external auth strategies by @michaelbromley in #4875
- feat(create): Add AI-assisted project guidance by @dlhck in #4850
- chore(repo): Back-merge master into minor by @michaelbromley in #4894
- feat(core): Add OrderLineDiscountDistributionStrategy to make proration configurable by @kevmtt in #4818
- fix(core): Refuse default superadmin credentials in production by @grolmus in #4718
- feat: Make cuopon code validation case insensitive by @Ryrahul in #4419
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4897
- feat(dashboard): Allow configuring TanStack Router plugin options by @grolmus in #4862
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4901
- test(create): Fix stale dev script assertion after master into minor merge by @michaelbromley in #4898
- chore(repo): Back-merge master into minor (conflicts) by @github-actions[bot] in #4903
- feat(dashboard): Allow user stylesheets to be passed to Dashboard build by @michaelbromley in #4905
- feat(dashboard): DataTable column view option defaults configurable via Plugin Extension API by @lucatk in #4197
- fix(dashboard): Filter dashboard extensions to plugins active in runtime config by @grolmus in #4732
- fix(deps): update runtime dependencies for security advisories by @michaelbromley in #4906
- fix(dashboard): Fix router basepath derivation in experimental bundle mode by @michaelbromley in #4908
Full Changelog: v3.6.5...v3.7.0