Run bin/console theme:create MyTheme on any Shopware 6.7 release up to 6.7.13, then open the generated composer.json. The package is called swag/theme-skeleton.
So is every other theme anyone has ever scaffolded with that command, on any project, regardless of the name they typed. The name was hardcoded in the template.
I know because I keep finding it. Enough client projects have handed me a production shop whose custom theme still declares swag/theme-skeleton that I check for it out of habit now. Nobody renames it. There is no reason a theme author would think to: the file arrives generated, and generated files look like they are already correct.
I sent a PR for that, along with the thing that bothered me more. Shopware theme:create only ever wrote a bare skeleton, and it never generated the parts every real theme needs. Both landed in Shopware 6.7.14.0 on 9 September 2026.
What theme:create gave you before
The default output is short. A composer.json, the plugin bootstrap class, theme.json, an empty overrides.scss, an empty base.scss, an empty main.js, and the dist folder for compiled JS.
Enough for Shopware to recognise the plugin as a theme, and little more. Three things it never wrote:
- A
config.xml. Without one, the theme has no settings screen in the admin. After 166 plugin builds I have not shipped a client theme that did not need one. - Snippet files. Any theme with custom Twig has custom text in it, and that text belongs in
storefront.de-DE.jsonandstorefront.en-GB.json. - Any SCSS organisation. One empty
base.scssand good luck. What follows is either a thousand-linebase.scssor a folder structure copied by hand out of whichever theme happened to be open in the next tab.
That copying is the real cost. The quality of your starting point depends on which theme you copied from and how old it was.
The composer.json that named every theme the same
Two problems sat in six lines of template.
// Before 6.7.14.0, for every theme, whatever you called it:
"name": "swag/theme-skeleton",
// ...and no require block at all.
// After:
"name": "custom/my-theme",
"require": {
"shopware/core": "~6.7.0"
}
swag/ is Shopware’s own vendor prefix, so the scaffold handed you a package claiming a namespace that is not yours. And with no require entry, Composer had no idea which Shopware the theme was written against, so it could never refuse an install that made no sense.
That is why the placeholder reaches production and stays there. It never breaks anything loudly, so it ships.
The generated name now follows the theme name. MyTheme becomes custom/my-theme.
This part applies whether or not you pass any of the new flags, because it corrects broken output rather than adding anything new.
The new theme:create flags
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 # all three at once
--with-config writes src/Resources/config/config.xml with one card and one text field, pointed at the current config XSD. A starting point rather than a finished settings screen, which is the intent: the file exists, the schema reference is correct, you fill in the rest.
--with-snippets writes src/Resources/snippet/storefront.de-DE.json and storefront.en-GB.json, both containing {}. Snippet discovery in current Shopware works off the filename, so those two are picked up with no PHP class and no services.xml entry. Worth knowing on its own, because plenty of theme guides still show that registration boilerplate.
--with-scss writes the 7-1 pattern that most SCSS codebases converge on anyway: abstracts/, base/, components/, layout/ and pages/, nine commented starter partials spread across them, and a base.scss that imports all nine in order.
// Abstracts
@import "abstracts/variables";
@import "abstracts/mixins";
// Base
@import "base/reset";
@import "base/typography";
// Components
@import "components/buttons";
--full is shorthand for all three.
Why three flags instead of one
The first version of the PR had a single --extended switch.
A Shopware maintainer pushed back on the name in review, and he was right. Extending a theme already means something specific in Shopware: inheriting from a parent through theme.json. A flag called --extended on the create command reads like it produces a child theme, which is not what it did.
His suggestion was --full, or a granular set, or both. I went with both. Granular flags let you take the SCSS structure without the config card, or the snippets without either. --full covers the case where you want everything and would rather not type three options.
Naming was the part I had thought about least and the part most likely to confuse whoever reads --help two years from now. That is what review is for.
Nothing changes if you do nothing
Bare theme:create MyTheme writes exactly what it wrote before. Same files, same empty base.scss, same directory layout.
That matters if you have a build script, a project template, or an onboarding doc that runs the command and expects a known set of files. All of it keeps working, because the new output is opt-in per flag.
The composer.json change is the exception, since it applies unconditionally. If anything in your tooling matches on the literal string swag/theme-skeleton, that is the one thing to check before you move a project to 6.7.14.0.
What it still does not do
theme.json is still generated with "author": "Shopware AG" in it. Every theme the command scaffolds credits Shopware as its author until somebody edits the file by hand.
I left that alone to keep the PR to one concern. It is a separate change and a separate PR.
Where it landed
Opened 10 July 2026. Merged 28 July 2026. Shipped in 6.7.14.0 on 9 September 2026, with its own entry in the release notes.
Six weeks between merge and release. 6.7.13.0 came out in between, on 5 August, without it, because the PR was tagged for the following line rather than that one. That is the ordinary rhythm of core contributions: the date filter fixes took two months from merge to shop, and the promotion discount fix took three weeks. Merged and shipped are different dates, sometimes by a lot.
What the placeholder tells you
composer.json is the first file in a theme. So when it still reads swag/theme-skeleton, nobody has opened that file since the day the theme was generated.
In my experience that holds for the rest of the theme too. The shops where I find the placeholder are the shops where the theme was scaffolded once, built on top of, and never revisited.
That makes it the cheapest signal I know when I inherit a Shopware project and have to work out how much of the theme somebody actually maintained. Ten seconds, one file.
If you build Shopware themes for clients, this is small and immediate. On 6.7.14.0 and up, theme:create MyTheme --full gives you a start you would otherwise assemble by hand from whatever was nearby, and your generated composer.json finally carries your theme’s name instead of Shopware’s.
If you already have themes in production, the official theme guide is still the reference for the parts around this. The two composer.json fields are worth fixing in place regardless of which version you are on.
Want this kind of attention on your own Shopware project? Get in touch, or read through the case studies first.
PR on GitHub: #18228, merged 28 July 2026 and shipped in 6.7.14.0. Contributor profile at github.com/zaifastafa.
Frequently asked questions
Which Shopware version do I need for the theme:create flags? 6.7.14.0, released 9 September 2026, and anything after it. Earlier 6.7 releases have theme:create with only the --static option. Shopware 6.6 and 6.5 have the command too, also without any scaffold flags. There is no backport, so on an older line you are copying these files in by hand as before.
Do the new flags change what plain theme:create outputs? No. Run it with no flags and you get exactly the files you got before, including the empty base.scss. The scaffolding is opt-in per flag. The one unconditional change is composer.json, which now carries a real package name and a shopware/core constraint whether you pass a flag or not.
What does --with-scss actually generate? A 7-1 folder structure under src/Resources/app/storefront/src/scss: abstracts, base, components, layout and pages, with nine commented starter partials spread across them, and a base.scss that imports all nine in order. Without the flag, base.scss stays an empty file, which is the old behaviour.
Do I need a PHP class to register the generated snippet files? No. Snippet discovery in current Shopware works off the filename, so storefront.de-DE.json and storefront.en-GB.json in src/Resources/snippet are picked up with no PHP class and no services.xml entry. Older theme guides still show that registration boilerplate, which is why the flag writes the files in the right place with the right names.
Is the composer.json fix worth applying to themes I already built? Yes, and it is worth checking rather than assuming, because the production themes I inherit routinely still carry the placeholder. It is a two-field edit: change the hardcoded swag/theme-skeleton name to your own vendor and theme, then add a shopware/core constraint under require. It costs a minute per theme and it means Composer can tell you when a theme and a core version disagree, instead of installing quietly and failing later.