What 164 Shopware 6 plugins taught me about building ones that last

After 164 custom plugins delivered across dozens of Shopware 6 projects, I’ve seen the same handful of mistakes break shops over and over.

A plugin runs cleanly for a year. The owner approves a Shopware update over the weekend. Monday morning, the admin won’t load. Orders are stuck. The agency says “we’ll look into it” and bills 30 hours.

That story is avoidable. Most of the time it’s not bad luck. It’s a plugin built the wrong way for the platform.

This post is for owners deciding who to trust with their shop, and for agency leads who want their plugins to age well.

Shopware 6 plays by its own rules

Most developers come to Shopware 6 from Magento, WooCommerce, or a generic Symfony app. The reflexes that work elsewhere quietly cost them on Shopware 6.

The platform has its own architecture, and some of its decisions look strange until they save your shop from a broken update. The most important one is how you extend Shopware’s own code.

Decoration: the pattern that keeps plugins alive

When a developer wants to change how Shopware ships an order, there are two paths.

Path one: copy Shopware’s class, change the bits they don’t like, and tell Shopware to use the copy. This is called overriding.

Path two: wrap Shopware’s class in a thin layer that adds the change on top, and leave Shopware’s original class alone. This is called decoration.

Shopware 6 is built around path two. The reason is mechanical. When Shopware updates the class next month and adds a new method, the wrapped version inherits it. The copied version doesn’t. The copied version slowly drifts out of sync with the parent until something goes wrong.

Decorated plugins keep working through Shopware updates. Overridden plugins quietly miss new features and start producing wrong results.

The Shopware docs cover the mechanics but not the judgement call. There are a few places where decoration is the wrong choice: cart calculation, search indexing, anything on a hot path where the extra layer adds milliseconds. In those cases, an event subscriber or a service replacement is the right move. For everything else, decorate.

If your agency reaches for class overrides by default, they’re building on path one. The cost is silent for now, and shows up at the next Shopware update.

The four mistakes that cost shops the most

I audit other agencies’ plugins regularly. Four issues come up over and over.

Overriding admin components instead of extending them. When Shopware updates the base component, the override goes silent. No error, just the wrong rendering or a missing field. Component extensions sit on top and inherit changes. Same idea as decoration, applied to the Vue admin instead of PHP services.

Plugins that hold state in shared services. Shopware reuses service instances across requests. If a service caches data from one request, the next request sees it too. The bug shows up as one customer seeing another customer’s data. By the time it’s noticed, the data leak is in the logs.

Skipping plugin lifecycle hooks. Shopware exposes install, update, activate, and deactivate hooks for a reason. Plugins that ignore them work on a fresh install and corrupt the database on update. I’ve seen one missing migration take a production shop offline for 8 hours.

Heavy work in synchronous event subscribers. A plugin that calls an external API every time a product is saved blocks the admin save until the API responds. When the API is slow, the admin feels broken. The fix is the message queue. Anything that takes longer than a request cycle goes there.

All four are avoidable. If a plugin is built around decoration and the message queue from day one, none of them happen.

When the data gets big

The Shopware data abstraction layer (DAL) is the standard way to read and write entities. It’s clean, it’s safe, and it falls over at scale.

On a project that imported 500,000+ SKUs, import time was 33 hours using DAL writes. Cutting that to under 3 hours meant three changes: batch processing with tunable chunk sizes, Redis-backed queuing for the async work, and direct DBAL writes for the bulk inserts where the DAL was the bottleneck.

The boundary worth knowing: under 10,000 entities per operation, the DAL is fine. Above that, benchmark before you commit. A plugin built for a 5,000-product shop will collapse on a 100,000-product shop unless someone designed for it.

Integrations are where shops actually fail

Most Shopware projects in the DACH region connect to ERPs (SAP, Microsoft Dynamics, Sage), PIMs (Akeneo, Pimcore), and warehouse systems. Standalone shops are rare. Each integration has its own data format, sync schedule, and ways of failing.

The pattern that holds up: a dedicated sync service per integration, each with its own retry logic, logging, and circuit breaker. Shop logic never depends on an external system being up. When the warehouse goes offline, the storefront stays online.

I built that pattern for a pharmaceutical distributor syncing 300,000+ SKUs with zero fulfillment errors, and for a B2B platform wiring real-time ERP quotes through OAuth2 REST APIs.

Migrating from Shopware 5

Many DACH shops still run Shopware 5, two years past its official end of life in July 2024. If you’re planning a migration, the headline is that Shopware 6 is a rewrite. Shopware 5 plugins are rebuilt against the new architecture.

The rebuild sounds expensive. It’s also the chance to clear years of technical debt in one motion. The replacement plugins use decoration, the new admin, and Flow Builder from day one. I’ve run full platform migrations with zero downtime by keeping both systems alive during the transition.

What to ask before signing

If you’re hiring an agency for a Shopware 6 project, four questions reveal a lot in one conversation.

  1. Do you decorate services or override them? “Decoration by default, override only with a reason” is the answer you want.
  2. Do you test plugins against production-scale data? A plugin that works for 1,000 products and falls over at 100,000 is common.
  3. How do you handle long-running work? Message queue is correct. Inside the event subscriber is not.
  4. How do you handle plugin updates on existing installations? Anything other than a real migration strategy is a red flag.

If your existing plugins are already in production and you suspect some of them were built the wrong way, an audit is worth a day of consulting time. An audit costs a day. Finding out during a Shopware update costs much more.

Where this leaves you

Shopware 6 is a different platform from anything else in PHP. The teams that treat it that way ship plugins that survive updates, scale with the catalog, and stop being a line item in next year’s maintenance budget.

If you’re running a Shopware 6 shop and want this kind of work done properly, get in touch. Specific projects are in the case studies.

Frequently asked questions

What is the decoration pattern in Shopware 6? Decoration wraps an existing service to add behaviour without replacing the original. Shopware 6 is built around it because decorated services keep working when Shopware updates the original, multiple plugins can decorate the same service without fighting each other, and a decorator can be tested by itself.

When is decoration the wrong choice? On hot paths like cart calculation or search indexing. The extra wrapper adds call overhead that matters at high volume. There, replacing the service or using a subscriber is the better call. Everywhere else, decorate.

How do you scale Shopware 6 plugins for large catalogs? Three moves: batch processing with tunable chunk sizes, Redis-backed queuing for async work, and direct DBAL writes for bulk inserts when the DAL is the bottleneck. Above 10,000 entities per operation, benchmark before committing to the DAL.

Can Shopware 5 plugins be ported to Shopware 6? No. Shopware 6 is a complete rewrite. Shopware 5 plugins get rebuilt from scratch against the new architecture using decoration, the new admin, and the message queue.

What causes Shopware 6 plugins to break during updates? Four common causes: overriding services instead of decorating them, overriding admin components instead of extending them, missing update migrations, and synchronous subscribers doing heavy work. All four are avoidable if the plugin is structured around decoration and the message queue from day one.

Share this article

Found this useful? Share it with your network

Huzaifa Mustafa

Huzaifa Mustafa

Shopware 6 certified developer with 164+ custom plugins delivered and 96+ clients across the DACH region. I write about Shopware architecture, e-commerce performance, and lessons from real projects.

Need help with Shopware?

Let's discuss how I can help with your e-commerce project.