shopware/conflicts
Composer plugin for Shopware that detects and prevents conflicts between extensions before installation. It checks declared conflicts and compatibility, helping keep plugin stacks stable and avoid runtime issues in Shopware projects.
shopware/conflicts is not a Laravel package — there is no service provider, facade, config file, or artisan command. It is a Composer plugin that runs during Composer lifecycle events and aborts install/update when it detects a package known to conflict with Shopware 6. Day-to-day, you “use” it by having it installed and allowed in the project where Composer runs.
Minimal setup:
# In the Shopware 6 project (or any Composer project you want guarded)
composer require --dev shopware/conflicts
# Composer 2.2+ requires explicit plugin permission
composer config allow-plugins.shopware/conflicts true
# Trigger the plugin
composer update
If the plugin is already pulled in transitively by a Shopware package, you only need the allow-plugins entry.
Where to look first:
vendor/shopware/conflicts/composer.json — find the declared plugin class and autoload mapping.vendor/shopware/conflicts/src/ — the plugin class and the conflict list/data source.composer.json — confirm whether the plugin is in require or require-dev, and confirm config.allow-plugins.First use case: install a package that the plugin knows is incompatible (or inspect the conflict list and pick one), then run composer require <package>. The expected behavior is a Composer error explaining the conflict instead of a successful install. That is the guardrail you are leveraging — it prevents a broken Shopware dependency graph before code is written.
For a Laravel developer, the practical scenario is: you maintain a Laravel app and a Shopware 6 plugin/storefront in the same organisation, or you are packaging a Laravel-based integration for Shopware. Keep shopware/conflicts in the Shopware project, not in the Laravel app, unless you explicitly want Composer-level conflict checks in the Laravel project too.
1. Treat it as a Composer guardrail, not application code
Do not try to call it from Laravel. There is nothing to inject. The plugin executes on Composer events such as package install/update, and its output is Composer console output. Your integration point is composer.json, composer.lock, CI scripts, and Dockerfiles.
2. Allow the plugin explicitly
Commit the permission so every environment behaves the same:
{
"config": {
"allow-plugins": {
"shopware/conflicts": true
}
}
}
This is especially important for non-interactive CI and Docker builds, where Composer cannot prompt.
3. Use it in the dependency-resolution workflow
A typical loop when adding a Shopware package:
composer require some/shopware-package
# If blocked:
# 1. Read the plugin's conflict message.
# 2. Check the conflict list in vendor/shopware/conflicts/src.
# 3. Remove the offending package or choose an alternative.
# 4. Re-run composer update.
Pair it with native Composer diagnostics:
composer why-not some/shopware-package 1.2.3
composer depends some/shopware-package
composer show --tree
Note that native why-not may not explain plugin-level conflicts; the plugin’s own message is often the only source.
4. CI pipeline pattern
Keep the plugin enabled in CI. A useful sequence:
composer validate --strict
composer install --no-interaction --prefer-dist
composer outdated --direct
Avoid --no-plugins in CI, because that silently disables the guardrail. If you must run a Composer command without plugins for an emergency, do it locally and document why.
5. Docker/local environment pattern
In a Dockerfile, set the allow-plugins config before composer install, otherwise builds hang or fail on Composer 2.2+ prompts:
RUN composer config --no-plugins allow-plugins.shopware/conflicts true \
&& composer install --no-interaction --no-dev --prefer-dist
Be careful with --no-dev: if shopware/conflicts is in require-dev, it will not be installed in production images. That may be intentional, but it means production builds do not get the same conflict checks.
6. Custom/forked conflict rules
If your organisation maintains its own set of incompatible packages, the practical pattern is to fork the plugin, add entries to its conflict list, and reference the fork via a VCS or path repository:
{
"repositories": [
{ "type": "path", "url": "../shopware-conflicts" }
],
"require-dev": {
"shopware/conflicts": "dev-main"
}
}
Keep this small. For simple package-level blocking, native Composer conflict entries are usually enough; use this plugin when you want Shopware-specific messaging or checks that native Composer cannot express.
7. Package-author testing pattern
If you publish a Shopware plugin or integration, test installation in a clean project with shopware/conflicts enabled before tagging a release. This catches accidental inclusion of blocked/legacy packages in your own dependency graph.
shopware/conflicts appears installed but does nothing, check config.allow-plugins. Without it, Composer may skip the plugin or prompt interactively.--no-plugins silently disables the guardrail. It is useful for debugging a broken Composer run, but never make it the default in scripts or CI.composer dump-autoload, static analysis, and application requests will not trigger conflict checks. Do not expect runtime protection.require-dev changes where the guardrail applies. With composer install --no-dev, the plugin is absent. Decide deliberately whether production images should enforce the same checks.vendor/shopware/conflicts/src and use composer why/composer depends to reconstruct the chain.composer why-not may not show plugin conflicts. The plugin is not part of Composer’s solver metadata, so its checks can be invisible to standard diagnostics.composer clear-cache and consider deleting vendor/ and composer.lock in a disposable environment before concluding the plugin is wrong.composer.lock.conflict section.allow-plugins in composer.json and use --no-interaction; otherwise a pipeline can hang waiting for a plugin permission prompt.composer update -vvv to see plugin event output and the exact point where installation is aborted.How can I help you explore Laravel packages today?