Shopify Theme Check: linting themes before they break
A linter for Liquid that catches unused snippets, missing translations, deprecated tags and the loops that make a store slow.
6 min read · APIs & data ·
Theme Check is a linter for Shopify themes. It reads your Liquid, JSON and settings files and reports mistakes — some cosmetic, several genuinely important. It's built into the CLI and takes about ten seconds to run.
``bash shopify theme check ``
Most theme projects never run it, which is a shame because it catches a specific class of problem that's invisible in review and obvious in production.
What it catches that matters
Performance problems. Nested loops over products and variants, unbounded iteration, expensive lookups repeated inside a loop. These are the patterns that make a collection page slow before a byte reaches the browser — the top item on the performance checklist.
Missing translation keys. A t filter referencing a key that doesn't exist in the locale file renders as the key itself. Customers see products.product.add_to_cart on a button. It's a one-line fix and it ships to production regularly — see localisation.
Deprecated tags and filters. {% include %} instead of {% render %}, old filters, things Shopify has moved on from.
Invalid schema. A malformed {% schema %} block means the section silently doesn't appear in the theme editor, which is a confusing failure to debug by hand.
Unused assets and snippets. Dead files accumulate through every redesign and nobody removes them.
Undefined objects. Referencing something that doesn't exist in that template's scope — a product object on the homepage, for instance.
Missing {{ content_for_header }} or {{ content_for_layout }}. Removing either breaks the store in ways that are hard to trace — theme file structure.
Configuring it
A .theme-check.yml at the theme root:
```yaml extends: theme-check:recommended
UnusedAssign: enabled: true severity: error
TranslationKeyExists: enabled: true severity: error
UndefinedObject: enabled: true
LiquidTag: enabled: false ```
Three presets ship with it — recommended, all and theme-app-extension. Start with recommended, then raise the severity of the checks you care about rather than enabling everything and drowning in noise.
Which checks to treat as errors
Not all findings are equal. The ones worth failing a build over:
- Missing translation keys — visible to customers.
- Invalid schema — silently breaks the theme editor.
- Undefined objects — usually a real bug.
- Deprecated tags — technical debt that gets worse.
- Nested loop warnings — performance, and expensive to fix later.
The rest can stay warnings.
Running it in CI
The highest-value place for it. Add it to your pipeline so a pull request that introduces a missing translation key or a deprecated tag fails before review:
``bash shopify theme check --fail-level error ``
That pairs naturally with keeping the theme in version control through the CLI workflow. Without version control there's nowhere sensible to run it.
What it doesn't catch
Being clear about the limits:
- It doesn't measure performance. It flags patterns that are usually slow; it doesn't tell you your LCP. Measure separately.
- It doesn't check accessibility. Missing labels, focus management and contrast need their own pass.
- It doesn't check design.
- It doesn't know your business rules.
It's a floor, not a ceiling.
Adopting it on an existing theme
Running it for the first time on a mature theme produces hundreds of findings, which is discouraging enough that most teams close the terminal and never return.
The workable approach: enable recommended, fix the errors only, ignore the warnings, and add checks one at a time as you clean up. A theme that fails cleanly on five important checks is far more useful than one where everyone ignores four hundred.
Ten seconds in CI catches the button that says products.product.add_to_cart to a customer. That's the entire argument.
Is this the problem you’re looking at?
Send me the link to your store and a line about what is going wrong. You get a straight answer within one business day — no pitch, no obligation.
mario@clicksandcarts.coOr see what I do around Shopify: services, work beyond the theme, selected work.