Shopware 6.6 to 6.7: What Actually Changes
6.7 is not a cosmetic release. It completes several migrations started in 6.6: Vuex→Pinia is now fully enforced (no Vuex APIs remain), Vue 2 compatibility is completely removed, Webpack is replaced by Vite in the admin build pipeline, and Redis transitions from optional-but-recommended to hard required. If you have plugins that touch the admin or extend core PHP classes, there is work to do.
The upside: the architectural disruption of 6.6 was the bigger jump. 6.7 refines and completes what 6.6 started. If your plugins are well-maintained and you’ve kept pace with 6.6.x deprecation warnings, the blast radius here is manageable.
What Changed: Overview
| Category | Scope | Impact |
|---|---|---|
| System requirements | Node.js 20+, Redis 7.0+ required, Symfony 7.4+ | Medium — must provision before upgrade |
| Admin: Webpack → Vite | All plugins with admin UI must rebuild | High — no cross-version compatibility |
| Admin: Pinia complete | Shopware’s internal stores migrated; Shopware.State deprecated (removed in 6.8) | High for plugins using state |
Admin: sw-* → mt-* enforced | Deprecated since 6.6; in 6.7 they work as wrappers but warn | Medium — codemods available |
| Admin: Vue 2 compat removed | $tc() deprecated (removed in 6.8), async component defaults | Medium — catch before deploy |
| Caching: delayed invalidation | Cache invalidates every ~5min, not immediately | Medium — plugins must adapt expectations |
| Caching: Store-API route cache | All Cached*Route classes removed | High for plugins extending these |
| Caching: ESI for header/footer | Requires ESI-capable HTTP layer | Medium — nginx/varnish config update |
| PHP: native types | All core properties have native types | High if you extend core classes |
| PHP: DBAL 4, PHPUnit 11 | API changes, test signature changes | Medium |
| PHP: payment handler rework | Old interfaces deprecated and replaced by AbstractPaymentHandler | High for shops with custom payment |
| PHP: OAuth scopes | Space-delimited string, /api/oauth/authorize removed | Low-Medium |
| Storefront | Accessibility defaults, ESI consequences, custom field names | Low-Medium |
Should You Upgrade Now?
This section is for shop owners and managers deciding when to pull the trigger. Developers implementing the upgrade should skip ahead to the technical sections.
Plugin ecosystem readiness
6.7 shipped in May 2025. As of early 2026, the major Shopware Store plugins have had time to publish compatible versions. This is meaningfully different from the first few months after a major release — the ecosystem has caught up. Before doing anything else, audit every installed plugin against the 6.7 compatibility badge in the Shopware Store.
For custom or agency-built plugins, the badge doesn’t exist. You need a code review. Any plugin with files in src/Resources/app/administration/ requires Vite and Pinia migration work for 6.7 — assume it’s needed unless someone has specifically verified it.
Cloud-hosted (SaaS) shops
If you are on Shopware’s cloud-hosted SaaS offering, Shopware controls the update timeline. You will be migrated on their schedule, not yours. Note: Rise, Evolve, and Beyond are commercial plan tiers — they can each be deployed as SaaS, PaaS, or self-hosted. If you self-host on any plan, you control your own update schedule. The notice period for SaaS is not generous. If you haven’t already audited plugin compatibility, do it now — before the notification arrives. Plugins with admin UI are the priority — the Webpack→Vite change means incompatible plugins will break visibly, immediately after the update.
Self-hosted on 6.6 LTS
If you’re on 6.6, you have options. Shopware 6.6 is LTS, which means approximately two years of security patches. There is no urgency to migrate to 6.7 today. The decision depends on:
- Redis: Already provisioned on your server? Upgrading is significantly simpler. Not provisioned? Add it to the scope and timeline — this is infrastructure work, not just a Composer update.
- Plugin count and type: Five or fewer marketplace plugins, no custom admin plugins: low-risk upgrade. Custom admin plugins, especially older ones: plan for significant work per plugin.
- Payment customizations: If you have custom payment handlers, they need to be rewritten to extend
AbstractPaymentHandler. This is not optional and not a small change — budget accordingly.
The honest decision framework
Go through this list:
- Check Redis: provisioned and 7.0+?
- Count plugins with admin UI. For each: is there a 6.7-compatible version?
- Do you have custom payment or shipping handlers?
- Do you have Varnish/nginx cache configuration for your storefront?
If the answers are all favorable, you’re likely looking at a focused week of work. If you hit multiple “no” or “unknown” answers, the estimate goes up. Audit first, then scope.
The Admin Overhaul
This is where the most work lives for plugin developers. Three changes that each require explicit migration.
Webpack → Vite
The admin build system moved from Webpack to Vite in 6.7. Build time for a typical plugin dropped from around two minutes to under twenty seconds — this is a genuine improvement. But it’s not free.
What breaks: Any plugin with a webpack.config.js in its administration directory no longer builds. The Webpack configuration is simply not used by the new toolchain.
What to change: Replace webpack.config.js with vite.config.mts in src/Resources/app/administration/src/:
// vite.config.mts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: {
entry: './src/main.js',
formats: ['iife'],
name: 'MyPlugin',
},
},
});
The exact configuration varies by plugin complexity. Shopware’s official migration guide covers the full Vite setup.
The version split problem: Shopware 6.6 uses Webpack; 6.7 uses Vite. These are not cross-compatible. If you maintain a plugin for both versions, you need separate releases — one targeting 6.6, one targeting 6.7. There is no single-file configuration that compiles correctly for both toolchains. Version your plugin accordingly and publish distinct packages.
Vuex → Pinia: Complete
In 6.6, Shopware began migrating internal stores from Vuex to Pinia. In 6.7, Shopware’s own internal stores have fully migrated to Pinia. Shopware.State is deprecated with console warnings in 6.7 and will be removed in 6.8. Third-party Vuex stores continue to work in 6.7, but you should migrate now to avoid 6.8 breakage. Everything should go through Shopware.Store.
The API change is straightforward but requires touching every place your plugin reads or writes state:
// Before (Vuex / 6.6 and earlier)
Shopware.State.registerModule('myStore', {
state: {},
getters: {},
mutations: {},
actions: {}
});
Shopware.State.get('myStore');
// After (Pinia / 6.7)
Shopware.Store.register('myStore', {
state: () => ({}), // state MUST be a function in Pinia
getters: {},
actions: {} // mutations are gone — put logic directly in actions
});
Shopware.Store.get('myStore');
Three things to internalize:
statemust be a function returning an object. Passing a plain object will not work.- Mutations are gone entirely. There’s no concept of a mutation in Pinia. Logic that lived in mutations moves to actions.
- The
registerModule/getpattern maps cleanly toregister/get— but search your codebase forShopware.Stateto find everything that needs updating.
The codemods can help here (see the Automated Tooling section).
sw-* → mt-* Now Enforced
The deprecation of sw-* components began in 6.6. In 6.7, they function as thin wrappers around mt-* components and continue to work, but generate console warnings. They are not removed in 6.7 — removal is planned for 6.8 or later. All new work and all migrated plugins should use mt-* components.
The quick reference:
| Old component | New component | Note |
|---|---|---|
sw-card | mt-card | |
sw-button | mt-button | |
sw-text-field | mt-text-field | |
sw-checkbox-field | mt-checkbox | Name shortened |
sw-select-field | mt-select | Name shortened |
sw-switch-field | mt-switch | Not mt-switch-field |
These are not pure renames — prop names, slot structures, and event names changed too. The codemods handle the bulk of it, but verify the result in the browser.
Run the official codemod:
composer run admin:code-mods -- --plugin-name MyPlugin --fix -v 6.7
This handles the sw-* → mt-* rename and the Pinia migration in one pass. Run it, then review the diff carefully before committing.
Vue 2 Compat: Fully Removed
The Vue 2 compatibility layer that shipped with Vue 3 in 6.6 is completely gone in 6.7.
$tc() deprecated. The plural translation function $tc() was deprecated in 6.6. In 6.7, it is deprecated with a warning and maps internally to $t(), but will be removed in 6.8. Some advanced overloads behave differently in the underlying vue-i18n v10. Replace all occurrences with $t() now to avoid 6.8 breakage:
// Before
this.$tc('my.translation.key', count)
// After
this.$t('my.translation.key', { count })
Async components are now the default. If your code assumed synchronous component resolution and accessed refs immediately after a render call, add await nextTick() before the access or restructure to wait for the component to mount.
Use @vue:mounted instead of trying to access component instances synchronously after they’ve been added to the DOM. The old pattern of setting a ref and immediately reading it in the same tick will return undefined.
Caching Architecture Changes
The caching layer in 6.7 is substantially different. If your shop has custom caching logic, reverse-proxy configuration, or plugins that depend on cache invalidation timing, read this section carefully.
Delayed Invalidation Is Now the Default
In 6.6 and earlier, editing an entity in the admin (a product, a category, a CMS block) invalidated the relevant HTTP cache entries immediately. In 6.7, invalidation is delayed.
By default, the cache is invalidated every five minutes via a scheduled task. This is intentional: it dramatically improves cache hit rates for high-traffic shops by preventing a single admin save from busting a large percentage of cached pages.
Impact for custom plugins: Any plugin that relied on “save in admin → immediately visible in storefront” behavior will appear to have a bug in 6.7. The page will update, but up to five minutes later.
If you need immediate invalidation for specific use cases, you have two options:
- Trigger
InvalidateHttpCacheTaskmanually after your entity update - Send
sw-force-cache-invalidate: 1in the HTTP header to bypass the delay for a specific request
Don’t trigger immediate invalidation globally — it defeats the performance improvement.
Redis Is Required
For multi-server or load-balanced production setups, Redis is effectively required for correct session and cache sharing. Single-server setups can technically run without it, but Redis is strongly recommended regardless of server count.
Important: if Redis is in use, the php-redis PHP extension must be version 6.1 or higher — this is a hard constraint due to Symfony 7.4’s composer dependencies.
Provision Redis before the upgrade. This is not something to do mid-migration — if you discover Redis isn’t available halfway through the update process, you’re in trouble. Check your server environment first.
Store-API Route Cache Removed
This is a significant breaking change for any plugin that extends the cached Store-API routes. All Cached*Route classes are gone:
CachedProductRouteCachedCategoryRouteCachedNavigationRouteCachedProductListingRoute- And all others in the pattern
If your plugin extended any of these classes — to inject data, add cache tags, or modify the cached response — it will throw a class-not-found error in 6.7. The replacement is HTTP-level caching rather than application-level route caching.
Use cache tags directly on your HTTP responses and configure your reverse proxy to honor them.
ESI for Header and Footer
The storefront header and footer are now loaded via Edge Side Includes (ESI) at /_esi/global/header and /_esi/global/footer. This means they’re cached separately from the main page and assembled at the HTTP layer.
Requirements: ESI support must be enabled at your HTTP layer — Symfony HttpCache, Nginx, or Varnish. If your deployment doesn’t support ESI, the header and footer will not render.
Plugin impact: If your plugin injected data into the page header or footer via GenericPageLoader, that path no longer works for header/footer content. Move your injections to HeaderPageletLoader or FooterPageletLoader.
Reverse proxy configuration: If you use Varnish, update from the old Redis ban method to XKey-based cache tagging. The Shopware documentation for the 6.7 hosting guide has the updated VCL configuration.
PHP and Backend Changes
Native Types on All Properties
Shopware 6.7 added native PHP type declarations to all core class properties. This is a clean-up that improves type safety across the codebase — but it’s a breaking change for any plugin that extends core classes without matching native type declarations.
If your plugin class extends a Shopware class and your property declarations don’t match, you’ll get a fatal error at runtime. PHP doesn’t allow a child class to have an untyped property where the parent declared a native type.
Fix: audit every class in your plugin that extends a Shopware class. Match native type declarations exactly.
// Core in 6.7 (simplified example)
class ProductEntity extends Entity
{
protected ?string $name = null;
protected float $price = 0.0;
}
// Your plugin extending it — must match types
class MyProductEntity extends ProductEntity
{
protected ?string $myCustomField = null; // fine
// protected $myCustomField = null; // fatal error in PHP 8.2+
}
DBAL 4, PHPUnit 11, Dompdf 3
Three dependency upgrades with their own breaking changes:
DBAL 4: The SchemaManager API changed. If your plugin has custom database schema management (migration classes, schema updates), check the DBAL 4 changelog. Foreign key naming convention changed from fk.<table>.<col> to fk__<table>__<col> — any migrations that reference FK names by string need updating.
PHPUnit 11: Test method signatures changed. If you have plugin unit tests, they likely need updates to setUp method signatures, assertion method names, and data provider syntax. This is mechanical work, but it’s mandatory if you run tests as part of your deployment pipeline.
Dompdf 3: If your shop or plugins generate PDF documents — invoices, delivery notes, credit notes — test all of them after the upgrade. Dompdf 3 has rendering changes that can affect layout. Don’t discover this in production.
Payment Handler Rework
This is the most significant PHP-level change in 6.7 for shops with custom payment integrations.
All previous payment handler interfaces are deprecated and replaced by AbstractPaymentHandler:
AsyncPaymentHandlerInterfaceSyncPaymentHandlerInterfacePreparedPaymentHandlerInterfaceRefundPaymentHandlerInterfaceRecurringPaymentHandlerInterface
The new pattern: extend AbstractPaymentHandler and use the single service tag shopware.payment.method. The specific handler type (sync, async, etc.) is determined by which methods you implement, not by which interface you implement.
Additionally, all payment methods and shipping methods now require a technicalName. For existing methods that don’t have one, Shopware’s migration will auto-assign a temporary_<id> value — but you should replace these with meaningful identifiers to avoid future confusion.
If you rely on any payment plugin maintained by a third party, check explicitly that it has been updated for 6.7. Outdated payment plugins cause checkout failures.
OAuth and API Changes
OAuth scopes must now be space-delimited strings. If you pass scopes as an array in your OAuth requests, they will fail in 6.7. Update to the string format: 'write read openid'.
/api/oauth/authorize removed. If you have any code or integrations hitting this endpoint directly, they need to be updated. Consult the 6.7 API documentation for the replacement flow.
Customer entity: Associations are no longer eager-loaded by default in Store-API responses for performance reasons. If you have code that assumed associated data would be present without explicit criteria, add the relevant associations to your criteria explicitly.
Many-to-many DAL: Missing foreign key fields in entity definitions now throw hard exceptions instead of logging silent warnings. If you have custom many-to-many entity definitions with incomplete field declarations, they will fail at runtime in 6.7.
Storefront and Template Changes
ESI Consequences for Plugins
With the header and footer moved to ESI, GenericPageLoader no longer provides header or footer data as part of the main page load. Plugins that used GenericPageLoader to inject data visible in the header or footer need to move to HeaderPageletLoader or FooterPageletLoader.
The ErrorTemplateStruct also no longer carries header and footer properties — error pages (404, 500, etc.) retrieve these separately. If your plugin customizes error templates and references these properties, update accordingly.
Accessibility Defaults
Several accessibility improvements that were gated behind the ACCESSIBILITY_TWEAKS feature flag in 6.6 are now the default in 6.7. This affects HTML structure in ways that can break CSS:
.product-image-link anchor removed. Product listing images no longer use a separate anchor wrapping the image. The product name link uses a stretched-link pattern instead. CSS rules targeting .product-image-link will have no effect.
Base font-size is now 1rem (16px). This is a browser-default alignment — but themes built with pixel-based sizing that assumed a different root font size may have layout regressions. Review your theme against the changed base.
Language and currency switchers now use <button> elements instead of <a>. CSS or JavaScript that targets these as anchors needs updating.
<ul>/<li> for cart and order items. The cart and order item lists now use semantic list markup. CSS targeting the old <div> structure will no longer match.
Custom Field Names
Custom field names may no longer contain hyphens or dots. These characters cause Twig template errors because the field names are used directly as Twig variable names, and Twig doesn’t permit hyphens or dots in variable identifiers.
If you created custom fields under 6.6 (or earlier) with names like my-custom-field or my.custom.field, these will cause Twig rendering failures in 6.7. Rename them to use underscores: my_custom_field.
The Upgrade Process: Step by Step
This order exists for a reason. Don’t reorder it.
-
Run the compatibility check first:
shopware-cli project upgrade-checkThis scans your installation and lists incompatibilities before you touch anything. Read the output fully.
-
Update your server environment:
- PHP 8.2+ (8.3 recommended)
- Node.js 20+
- Redis 7.0+
Do this before updating Shopware. Environment and application changes on the same step obscure which one caused a problem.
-
Provision Redis if it’s not already available. Add it to your
framework.yamlor.envas your cache adapter. -
Assign the default Shopware theme to any sales channels that use a fully custom theme without inheriting from Shopware’s default. This prevents theme compilation failures during the upgrade.
-
Read
UPGRADE-6.7.mdin the Shopware GitHub repository. It is the source of truth, not this post. Every breaking change Shopware is aware of is documented there. -
Enable maintenance mode:
bin/console sales-channel:maintenance:enable --all -
Update
composer.jsonto target 6.7 and run:composer update --no-scripts -
Apply Symfony Flex recipe updates:
composer recipes:updateReview the diff carefully. Don’t accept all updates blindly — some may overwrite configuration you’ve customized.
-
Run the database preparation step:
bin/console system:update:prepare -
Run the update completion step:
bin/console system:update:finish -
Migrate admin plugins: Apply the Vite configuration, run the Pinia state migration, and execute
mt-*codemods for each plugin with admin UI. -
Rebuild all assets:
bin/console theme:compile && bin/console assets:install && bin/console cache:clear -
Test thoroughly:
- Admin: open every module your plugins add or modify
- Storefront: full browse → add to cart → checkout flow
- Payments: test every active payment method end-to-end
- PDFs: generate an invoice, a delivery note, a credit note
- ESI: verify header and footer render correctly
- Caching: check that pages render correctly after cache clear
-
Disable maintenance mode:
bin/console sales-channel:maintenance:disable --all
Automated Tooling
You don’t have to do all of this manually.
shopware-cli project upgrade-check — Run before anything else. Scans your installation against the 6.7 compatibility matrix and lists what will break. The output shapes your entire migration effort.
shopware-cli extension validate ./path/to/plugin --full — Detailed validation of a specific plugin. Useful after you’ve made changes to verify the plugin passes Shopware’s checks before running the full upgrade.
Official codemods — Automate the sw-* → mt-* rename and the Vuex → Pinia migration in one command:
composer run admin:code-mods -- --plugin-name MyPlugin --fix -v 6.7
Run this, then read the diff. It handles the bulk of component renames and state API changes, but it doesn’t cover every edge case. Manual review after the codemod is not optional.
Rector for PHP — If you have multiple plugins or a large PHP codebase, Rector can automate native type additions, class renames, and method signature updates for the PHP-level breaking changes. Configure it with Shopware’s Rector rules from the shopware/shopware-rector package.
Twig block versioning (PHPStorm plugin) — If you override Shopware core Twig blocks in your storefront templates, this plugin tracks upstream block changes and alerts you when a block you’ve overridden has been modified in the core. Useful for catching broken template overrides without manually diffing every block.
Frequently Asked Questions
Can I skip 6.6 and go straight to 6.7?
Technically yes — Shopware allows version jumps. But you don’t escape the 6.6 breaking changes by skipping: the Vue 3 migration, the all.js removal, the Symfony 7 upgrade, and the removed deprecated PHP APIs all still apply in 6.7. You’ll be debugging two releases’ worth of breakage at the same time, with fewer debugging reference points. Unless you have a specific reason to jump, go through 6.6 first, stabilize, and then approach 6.7 as a separate project.
Is Redis required in 6.7?
For multi-server or load-balanced production setups, yes — Redis is effectively required for correct session and cache sharing. Single-server setups can technically run without it, but Redis is strongly recommended regardless. If Redis is in use, the php-redis extension must be 6.1+ due to a Symfony 7.4 constraint. Provision it before you start the upgrade.
Will Shopware cloud-hosted (SaaS) shops be auto-updated to 6.7?
If you are on Shopware’s SaaS (cloud-hosted) deployment, yes — Shopware controls the update schedule. Rise, Evolve, and Beyond are commercial plan tiers that can each run as SaaS, PaaS, or self-hosted. Only the SaaS deployment model is auto-updated by Shopware. The practical implication: you may have less time to react than you think. Audit your plugin compatibility now — before the update notification arrives. Plugins with admin UI are the ones to focus on, because the Webpack→Vite change means incompatible admin plugins will break visibly for your team immediately after the update.
Do plugins need separate versions for 6.6 and 6.7?
Yes, for any plugin with admin UI. The Webpack→Vite change in the admin build system is not backwards-compatible. A plugin compiled for 6.6’s Webpack pipeline will not load correctly in 6.7’s Vite pipeline, and vice versa. You need distinct plugin releases for each major version. If you’re a plugin developer, version your releases clearly and publish both.
Where to Go From Here
Start with the audit. shopware-cli project upgrade-check on your installation, followed by a manual review of every plugin with admin UI. That output determines everything else about your scope and timeline.
If you skipped the 6.5 → 6.6 migration and are encountering those changes for the first time, the 6.5 to 6.6 migration guide covers the Vue 3 admin migration, all.js removal, and Symfony 7 changes in detail — those still apply if you’re jumping from 6.5.
For context on how Shopware is structured and what you’re actually running before you start changing things, the Shopware 6 platform overview is a useful starting point.
If you have a specific migration coming up and want a second opinion on what the scope actually looks like — reach out. I’ll tell you what I see in the code, not what’s convenient to hear.