In a migration from Shopware 5 to 6, everybody talks about the data first. Products, customers, orders, categories: that is the visible part, there are tools for it, and in most projects it is the smaller effort.
The bigger effort sits in the plugins, for a structural reason: Shopware 6 is not a new version of Shopware 5, it is a different application. No plugin for 5 runs in 6. Not "with adjustments", but not at all.
That makes every installed plugin a decision of its own, and the sum of those decisions determines whether the migration takes three months or a year. This article describes how to make them before anybody puts a number on the work.
Taking stock: three lists, not one
The question "which plugins do you have" usually gets answered with a look at the admin panel. That produces a list which is too long, because it mixes installed with used. Three lists are needed, and they differ more than expected.
Installed. Everything sitting in the shop. Regularly includes plugins somebody tried out years ago.
Active. The subset that is switched on. Readable straight from the database, and that comparison alone often halves the list.
-- Shopware 5: installed and active, with origin
SELECT name, label, version, active, installation_date, source
FROM s_core_plugins
WHERE source IS NOT NULL
ORDER BY active DESC, source, name;Effective. The subset that actually does something. An active plugin whose feature nobody uses is a candidate for deletion at migration time, and that list exists nowhere. It comes from three sources: query logs for plugins with their own tables, the web server log for plugins with their own pages, and a conversation with whoever runs the shop for the rest.
The return on that separation is considerable. In the projects I have seen, the list of effective plugins was regularly half as long as the list of installed ones. Every deleted entry is effort that does not arise.
Four categories, four answers
What is left sorts into four groups. That classification is the actual work of taking stock, and it takes five to twenty minutes per plugin.
One: there is a version for Shopware 6. The vendor ported the plugin. That is the best case and still not free: the version for 6 often has a different feature set, different settings and a different interface. The effort sits in configuration and testing, not in development.
Two: the feature is built into Shopware 6. A substantial share of what needed a plugin in 5 is part of the core in 6. That is the most pleasant category, because the effort is negative: one dependency fewer. The check is still needed, because "built in" does not mean "identical".
Three: there is a different vendor. The feature exists, from somebody else. What decides here is not the feature list but the question of what happens to the old plugin's data. A product review plugin has stored reviews, and nobody wants to lose those.
Four: there is nothing. That is the expensive case, and it almost always hits the in-house work and the adjustments made for this one shop. Every one of those plugins is a small project of its own, and the sum of them is the duration of the migration.
For planning, what matters is that the fourth category gets settled first. It determines the scope, and it is the only one where estimating is genuinely hard.
In-house plugins: how much of that is really business logic
For in-house work, a second question is worth asking before anybody rebuilds it: does this have to be a plugin at all?
In grown shops, in-house plugins regularly hold logic that only ended up there because in Shopware 5 it was the only place to put code. Three patterns keep coming up.
An integration with another system. A plugin that hands orders over to the ERP overnight. That is not a shop feature, it is an interface, and it is better off outside the shop: as a small service of its own that reads and writes through the Shopware 6 API. That way it survives the next migration.
A pricing or discount rule. Often the actual business logic of the company, hidden in a plugin. Here it is worth checking whether Shopware 6 can express it with its own means. Frequently it can, and then the answer is configuration rather than code.
A presentation tweak. A plugin that makes a page look different. In 6 that belongs in the theme, not in a plugin, and the rebuild is usually smaller than the port.
That sorting is where a migration turns into a clean-up: what would have to be rebuilt as a plugin is often a third of what was installed.
The theme is the underestimated item
In almost every quote the theme is one line, and in almost every project it is one of the largest single items.
The reason is the same as with plugins: Shopware 6 has a different template language, a different theme system and a different way of building interface components. A theme from 5 does not get ported, it gets rebuilt.
What determines the order of magnitude is not the appearance but the number of deviations from the standard. That can be counted before the migration, and the number is usually surprising:
# Shopware 5: how many standard templates are overridden?
find themes/Frontend/*/frontend -name "*.tpl" | wc -l
# And how many of those actually differ rather than merely existing?
for f in $(find themes/Frontend/*/frontend -name "*.tpl"); do
orig="engine/Shopware/Themes/Frontend/Bare/${f#*frontend/}"
[ -f "$orig" ] && ! diff -q "$f" "$orig" >/dev/null && echo "$f"
done | wc -lTwenty overridden templates is a manageable theme. Two hundred is a project of its own, and then the honest question is whether the new shop really needs the same two hundred deviations or whether part of them is history.
What a project like this costs overall and which items are missing from the first quote is covered in What a modernization costs.
The order: plugins before data
From taking stock follows an order that contradicts the usual approach and that noticeably affects how long the project runs.
- Produce the three lists and settle the fourth category. One week, and after that the scope is known rather than estimated.
- Decide the theme. Start fresh on the standard or rebuild the deviations. That is a decision, not a task, and it belongs before implementation.
- Build the missing plugins, on an empty Shopware 6 with sample data. Without real data, because it is not needed yet.
- Only then migrate the data. The tools for it are mature, the run is repeatable, and it will run several times.
- Parallel operation and switchover.
The fourth item is the surprising one. Data migration is often the first and largest position in a quote. It is repeatable and therefore not dangerous: a run that is wrong gets corrected and repeated. A missing plugin, by contrast, holds up the entire switchover.
Running two states side by side is a topic of its own: Dual write and backfill.
Parallel operation and the point of no return
Unlike a framework upgrade, a shop replacement normally runs in parallel: the old shop runs, the new one gets built, and at some point the switch happens.
Two things decide how risky that moment becomes.
The data migration runs several times, the last of them shortly before the switch. Anything else means the orders of the last few days are missing. That final run gets rehearsed, with a measured duration, because the switchover window follows from it.
The redirects for the old URLs are in place before the switch. A shop with search visibility loses it when the old addresses lead nowhere. The old-to-new mapping comes out of the data and belongs in the same release as the switch, not in the week after.
The way back is to undo the redirect and point at the old shop again. It ends the moment the first order arrives in the new shop, and it ends irreversibly: entering that order in the old shop is no longer a technical task, it is manual work in accounting.
So before the switch comes a sober check of the core paths: find a product, add to basket, order, pay, receive confirmation, arrive in the ERP. Not as a click list, but with real payment methods in an environment that matches production.
How I set up a Shopware migration is on its own page. Taking stock as described above is the first block of work there, and it is worth doing even if somebody else runs the migration afterwards.
This article belongs to a series about systems that already exist. The retrospective orders every article in it by situation.

