Führen Sie bin/console theme:create MyTheme auf einem beliebigen Shopware-6.7-Release bis 6.7.13 aus und öffnen Sie danach die erzeugte composer.json. Das Paket heisst swag/theme-skeleton.
Und zwar bei jedem Theme, das jemals mit diesem Befehl angelegt wurde, in jedem Projekt, unabhängig vom eingegebenen Namen. Der Name stand fest im Template.
Ich weiss das, weil ich es immer wieder finde. Genug Kundenprojekte haben mir einen Produktivshop übergeben, dessen eigenes Theme weiterhin swag/theme-skeleton deklariert, dass ich inzwischen aus Gewohnheit danach schaue. Niemand benennt es um. Es gibt auch keinen Grund, warum ein Theme-Autor darauf käme: Die Datei kommt generiert, und generierte Dateien sehen aus, als wären sie bereits richtig.
Dafür habe ich einen PR eingereicht, zusammen mit der Sache, die mich mehr gestört hat. Shopware theme:create schrieb immer nur ein nacktes Gerüst und erzeugte nie die Teile, die jedes echte Theme braucht. Beides ist am 9. September 2026 mit Shopware 6.7.14.0 erschienen.
Was theme:create bisher lieferte
Die Standardausgabe ist kurz. Eine composer.json, die Plugin-Bootstrap-Klasse, theme.json, eine leere overrides.scss, eine leere base.scss, eine leere main.js und der dist-Ordner für kompiliertes JS.
Genug, damit Shopware das Plugin als Theme erkennt, und kaum mehr. Drei Dinge hat der Befehl nie geschrieben:
- Eine
config.xml. Ohne sie hat das Theme keine Einstellungsseite im Admin. Nach 166 Plugin-Builds habe ich kein Kunden-Theme ausgeliefert, das ohne ausgekommen wäre. - Snippet-Dateien. Jedes Theme mit eigenem Twig hat eigene Texte darin, und die gehören in
storefront.de-DE.jsonundstorefront.en-GB.json. - Irgendeine SCSS-Struktur. Eine leere
base.scss, und viel Glück. Was danach entsteht, ist entweder einebase.scssmit tausend Zeilen oder eine von Hand kopierte Ordnerstruktur aus dem Theme, das gerade im Nachbartab offen war.
Dieses Kopieren ist der eigentliche Preis. Die Qualität Ihres Startpunkts hängt davon ab, aus welchem Theme Sie kopiert haben und wie alt es war.
Die composer.json, die jedes Theme gleich nannte
Zwei Probleme steckten in sechs Zeilen Template.
// Vor 6.7.14.0, bei jedem Theme, egal wie Sie es genannt haben:
"name": "swag/theme-skeleton",
// ...und gar kein require-Block.
// Danach:
"name": "custom/my-theme",
"require": {
"shopware/core": "~6.7.0"
}
swag/ ist Shopwares eigenes Vendor-Präfix. Das Gerüst gab Ihnen also ein Paket, das einen Namensraum beansprucht, der Ihnen nicht gehört. Und ohne require-Eintrag wusste Composer nicht, gegen welches Shopware das Theme geschrieben war, konnte eine unsinnige Installation also nie ablehnen.
Deshalb schafft es der Platzhalter bis in die Produktion und bleibt dort. Er geht nie laut kaputt, also wird er ausgeliefert.
Der erzeugte Name folgt jetzt dem Theme-Namen. Aus MyTheme wird custom/my-theme.
Dieser Teil greift unabhängig davon, ob Sie eine der neuen Optionen setzen, denn er korrigiert kaputte Ausgabe, statt etwas Neues hinzuzufügen.
Die drei neuen theme:create-Optionen
bin/console theme:create MyTheme --with-config
bin/console theme:create MyTheme --with-snippets
bin/console theme:create MyTheme --with-scss
bin/console theme:create MyTheme --full # alle drei auf einmal
--with-config schreibt src/Resources/config/config.xml mit einer Card und einem Textfeld, verweisend auf das aktuelle Config-XSD. Ein Startpunkt und keine fertige Einstellungsseite, und genau das ist die Absicht: Die Datei existiert, die Schema-Referenz stimmt, den Rest füllen Sie.
--with-snippets schreibt src/Resources/snippet/storefront.de-DE.json und storefront.en-GB.json, beide mit dem Inhalt {}. Die Snippet-Erkennung im aktuellen Shopware läuft über den Dateinamen, die beiden werden also ohne PHP-Klasse und ohne services.xml-Eintrag gefunden. Das allein ist schon wissenswert, denn viele Theme-Anleitungen zeigen diese Registrierung noch.
--with-scss schreibt das 7-1-Muster, auf das die meisten SCSS-Codebasen ohnehin zulaufen: abstracts/, base/, components/, layout/ und pages/, darauf verteilt neun kommentierte Start-Partials, und eine base.scss, die alle neun der Reihe nach importiert.
// Abstracts
@import "abstracts/variables";
@import "abstracts/mixins";
// Base
@import "base/reset";
@import "base/typography";
// Components
@import "components/buttons";
--full ist die Kurzform für alle drei.
Warum drei Optionen statt einer
Die erste Fassung des PRs hatte einen einzelnen Schalter --extended.
Ein Shopware-Maintainer hat den Namen im Review beanstandet, und er hatte recht. Ein Theme zu erweitern bedeutet in Shopware bereits etwas Bestimmtes: von einem Eltern-Theme über theme.json zu erben. Eine Option namens --extended am Create-Befehl liest sich, als würde sie ein Child-Theme erzeugen, was sie nicht tat.
Sein Vorschlag war --full, oder ein granularer Satz, oder beides. Ich habe beides gemacht. Die granularen Optionen erlauben die SCSS-Struktur ohne die Config-Card oder die Snippets ohne beides. --full deckt den Fall ab, in dem man alles will und nicht drei Optionen tippen möchte.
Der Name war der Teil, über den ich am wenigsten nachgedacht hatte, und der Teil, der jemanden beim Lesen von --help in zwei Jahren am ehesten verwirrt hätte. Dafür ist ein Review da.
Wer nichts tut, ändert nichts
Ein blankes theme:create MyTheme schreibt exakt das, was es vorher geschrieben hat. Gleiche Dateien, gleiche leere base.scss, gleiches Verzeichnislayout.
Das ist wichtig, wenn Sie ein Build-Skript, ein Projekt-Template oder eine Onboarding-Doku haben, die den Befehl ausführt und einen bekannten Satz Dateien erwartet. All das läuft weiter, denn die neue Ausgabe ist pro Option zuschaltbar.
Die composer.json ist die Ausnahme, weil sie sich in jedem Fall ändert. Wenn irgendetwas in Ihrem Tooling auf die Zeichenkette swag/theme-skeleton matcht, ist das die eine Stelle, die Sie vor dem Sprung auf 6.7.14.0 prüfen sollten.
Was er weiterhin nicht tut
Die theme.json wird nach wie vor mit "author": "Shopware AG" erzeugt. Jedes Theme, das der Befehl anlegt, nennt Shopware als Autor, bis jemand die Datei von Hand ändert.
Das habe ich bewusst liegen gelassen, damit der PR bei einem Thema bleibt. Es ist eine eigene Änderung und ein eigener PR.
Wo der PR gelandet ist
Eröffnet am 10. Juli 2026. Gemerged am 28. Juli 2026. Ausgeliefert mit 6.7.14.0 am 9. September 2026, mit einem eigenen Eintrag in den Release Notes.
Sechs Wochen zwischen Merge und Release. 6.7.13.0 erschien dazwischen, am 5. August, ohne den PR, weil er für die folgende Linie getaggt war und nicht für diese. Das ist der gewöhnliche Rhythmus von Core-Beiträgen: Die Datumsfilter-Fixes brauchten vom Merge bis in den Shop zwei Monate, der Promotion-Rabatt-Fix drei Wochen. Gemerged und ausgeliefert sind zwei verschiedene Daten, manchmal weit auseinander.
Was der Platzhalter verrät
Die composer.json ist die erste Datei eines Themes. Steht dort weiterhin swag/theme-skeleton, hat sie seit dem Tag der Generierung niemand mehr geöffnet.
Meiner Erfahrung nach gilt das für den Rest des Themes ebenso. Die Shops, in denen ich den Platzhalter finde, sind die Shops, in denen das Theme einmal generiert, danach überbaut und nie wieder angefasst wurde.
Damit ist es das billigste Signal, das ich kenne, wenn ich ein Shopware-Projekt übernehme und einschätzen muss, wie viel am Theme tatsächlich gepflegt wurde. Zehn Sekunden, eine Datei.
Wenn Sie Shopware-Themes für Kunden bauen, ist das hier klein und sofort nutzbar. Ab 6.7.14.0 gibt Ihnen theme:create MyTheme --full einen Start, den Sie sonst aus dem zusammensetzen, was gerade in der Nähe liegt, und Ihre erzeugte composer.json trägt endlich den Namen Ihres Themes statt den von Shopware.
Wenn Sie bereits Themes im Einsatz haben, bleibt der offizielle Theme-Guide die Referenz für alles drumherum. Die zwei composer.json-Felder lohnen sich unabhängig von Ihrer Version.
Sie wollen diese Art von Sorgfalt in Ihrem eigenen Shopware-Projekt? Melden Sie sich, oder schauen Sie vorher in die Case Studies.
PR auf GitHub: #18228, gemerged am 28. Juli 2026 und ausgeliefert in 6.7.14.0. Contributor-Profil unter github.com/zaifastafa.
Häufige Fragen
Welche Shopware-Version brauche ich für die theme:create-Optionen? 6.7.14.0, veröffentlicht am 9. September 2026, und alles danach. Frühere 6.7-Releases haben theme:create nur mit der Option --static. Shopware 6.6 und 6.5 haben den Befehl ebenfalls, auch dort ohne Scaffold-Optionen. Einen Backport gibt es nicht, auf einer älteren Linie kopieren Sie diese Dateien also weiterhin von Hand.
Ändern die neuen Optionen die Ausgabe von einfachem theme:create? Nein. Ohne Optionen bekommen Sie exakt die Dateien wie vorher, inklusive der leeren base.scss. Das zusätzliche Scaffolding ist pro Option zuschaltbar. Die einzige Änderung, die immer greift, ist die composer.json: Sie trägt jetzt einen echten Paketnamen und eine shopware/core-Anforderung, ganz gleich ob Sie eine Option setzen oder nicht.
Was erzeugt --with-scss genau? Eine 7-1-Ordnerstruktur unter src/Resources/app/storefront/src/scss: abstracts, base, components, layout und pages, verteilt darauf neun kommentierte Start-Partials, und eine base.scss, die alle neun der Reihe nach importiert. Ohne die Option bleibt base.scss eine leere Datei, also das alte Verhalten.
Brauche ich eine PHP-Klasse, um die erzeugten Snippet-Dateien zu registrieren? Nein. Die Snippet-Erkennung im aktuellen Shopware läuft über den Dateinamen. storefront.de-DE.json und storefront.en-GB.json in src/Resources/snippet werden also ohne PHP-Klasse und ohne services.xml-Eintrag gefunden. Ältere Theme-Anleitungen zeigen diese Registrierung noch, und genau deshalb legt die Option die Dateien am richtigen Ort mit den richtigen Namen an.
Lohnt sich der composer.json-Fix für Themes, die ich schon gebaut habe? Ja, und Sie sollten nachsehen statt es anzunehmen, denn die Produktiv-Themes, die ich übernehme, tragen den Platzhalter regelmässig noch. Es sind zwei Felder: Ersetzen Sie den fest verdrahteten Namen swag/theme-skeleton durch Ihren eigenen Vendor und Theme-Namen, und ergänzen Sie unter require eine shopware/core-Anforderung. Das kostet eine Minute pro Theme, und danach kann Composer Ihnen sagen, wenn Theme und Core-Version nicht zusammenpassen, statt still zu installieren und später zu scheitern.