Shopware 6.6 to 6.7: What Actually Changes

• by Tobias Schäfer • 18 min read

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

CategoryScopeImpact
System requirementsNode.js 20+, Redis 7.0+ required, Symfony 7.4+Medium — must provision before upgrade
Admin: Webpack → ViteAll plugins with admin UI must rebuildHigh — no cross-version compatibility
Admin: Pinia completeShopware’s internal stores migrated; Shopware.State deprecated (removed in 6.8)High for plugins using state
Admin: sw-*mt-* enforcedDeprecated since 6.6; in 6.7 they work as wrappers but warnMedium — codemods available
Admin: Vue 2 compat removed$tc() deprecated (removed in 6.8), async component defaultsMedium — catch before deploy
Caching: delayed invalidationCache invalidates every ~5min, not immediatelyMedium — plugins must adapt expectations
Caching: Store-API route cacheAll Cached*Route classes removedHigh for plugins extending these
Caching: ESI for header/footerRequires ESI-capable HTTP layerMedium — nginx/varnish config update
PHP: native typesAll core properties have native typesHigh if you extend core classes
PHP: DBAL 4, PHPUnit 11API changes, test signature changesMedium
PHP: payment handler reworkOld interfaces deprecated and replaced by AbstractPaymentHandlerHigh for shops with custom payment
PHP: OAuth scopesSpace-delimited string, /api/oauth/authorize removedLow-Medium
StorefrontAccessibility defaults, ESI consequences, custom field namesLow-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:

  1. Check Redis: provisioned and 7.0+?
  2. Count plugins with admin UI. For each: is there a 6.7-compatible version?
  3. Do you have custom payment or shipping handlers?
  4. 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:

  1. state must be a function returning an object. Passing a plain object will not work.
  2. Mutations are gone entirely. There’s no concept of a mutation in Pinia. Logic that lived in mutations moves to actions.
  3. The registerModule/get pattern maps cleanly to register/get — but search your codebase for Shopware.State to 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 componentNew componentNote
sw-cardmt-card
sw-buttonmt-button
sw-text-fieldmt-text-field
sw-checkbox-fieldmt-checkboxName shortened
sw-select-fieldmt-selectName shortened
sw-switch-fieldmt-switchNot 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:

  1. Trigger InvalidateHttpCacheTask manually after your entity update
  2. Send sw-force-cache-invalidate: 1 in 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:

  • CachedProductRoute
  • CachedCategoryRoute
  • CachedNavigationRoute
  • CachedProductListingRoute
  • 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.

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:

  • AsyncPaymentHandlerInterface
  • SyncPaymentHandlerInterface
  • PreparedPaymentHandlerInterface
  • RefundPaymentHandlerInterface
  • RecurringPaymentHandlerInterface

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.

  1. Run the compatibility check first:

    shopware-cli project upgrade-check

    This scans your installation and lists incompatibilities before you touch anything. Read the output fully.

  2. 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.

  3. Provision Redis if it’s not already available. Add it to your framework.yaml or .env as your cache adapter.

  4. 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.

  5. Read UPGRADE-6.7.md in the Shopware GitHub repository. It is the source of truth, not this post. Every breaking change Shopware is aware of is documented there.

  6. Enable maintenance mode:

    bin/console sales-channel:maintenance:enable --all
  7. Update composer.json to target 6.7 and run:

    composer update --no-scripts
  8. Apply Symfony Flex recipe updates:

    composer recipes:update

    Review the diff carefully. Don’t accept all updates blindly — some may overwrite configuration you’ve customized.

  9. Run the database preparation step:

    bin/console system:update:prepare
  10. Run the update completion step:

    bin/console system:update:finish
  11. Migrate admin plugins: Apply the Vite configuration, run the Pinia state migration, and execute mt-* codemods for each plugin with admin UI.

  12. Rebuild all assets:

    bin/console theme:compile && bin/console assets:install && bin/console cache:clear
  13. 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
  14. 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.

Working on a Shopware project?

I'm available for consulting, development, and code reviews. Get in touch.

Related Posts