THEME · TECHNICAL · PERFORMANCE · 7 JULY 2026 · 8 MIN READ
Refactoring a theme without a redesign budget
A theme refactor is the project nobody will fund, because it produces no screenshot. Done in the right order it is also the one that makes every later change cheaper.
Incrementally, and behind an unchanged design. A Shopify theme refactor works when every step leaves the rendered page identical, so nothing needs sign-off from anyone but you: delete what is dead, then consolidate what is duplicated, then restructure what is load-bearing. Shopify’s own Theme Check finds most of the first category for you, the GitHub integration gives you a branch per theme to do it in, and the published theme never moves until a step is proven.
IN SHORT
- A refactor that changes the rendered output is not a refactor — it is a redesign with no design review, and it will be blamed for the next conversion dip.
- Theme Check is Shopify’s linter for the Liquid and JSON in a theme, and it reports orphaned snippets and unused variables directly.
- The `OrphanedSnippet` and `UnusedAssign` checks are how you find dead code without reading the whole theme.
- Shopify’s GitHub integration connects one branch to one theme and syncs in both directions, so a refactor branch is a previewable theme without touching the live one.
- Shopify commits theme editor and code editor changes back to the connected branch, so anyone editing in the admin during your refactor is committing to your repository.
- Do the work in the order dead code, then duplication, then structure — each stage makes the next one smaller and safer.
- Refactoring a template nobody will change again is wasted money; pick the files the roadmap is about to touch.
The constraint that makes this possible
The reason theme refactors do not get funded is that they have nothing to show. A redesign produces a before and after. A refactor produces a page that looks exactly the same, and an engineer saying it is better underneath. That is a hard sell in a room deciding between this and a new landing page template.
But the same property that makes it a hard sell is what makes it possible to do at all without a budget: if the rendered output does not change, nobody has to approve it. No design review, no stakeholder walkthrough, no waiting for the marketing calendar to clear. A refactor is one of the very few pieces of work on a trading store that can proceed on any Tuesday.
That only holds if you are disciplined about it. The moment a refactor also fixes the spacing on the product page because the developer was in there anyway, it becomes a change that needs review, and the whole economic argument collapses. Worse, when conversion dips three weeks later for unrelated reasons, the refactor is the thing that changed and the thing that gets blamed. Keep the pixels fixed. Write down the one or two places where you genuinely cannot — a rounding difference in a grid gap, a markup change that shifts a focus ring — and get those looked at deliberately.
Stage one: delete before you improve
Every refactor should start with removal, because deleting a file is the only change that is guaranteed not to introduce a bug in the code you keep, and because it shrinks the surface of everything that follows. A theme that has been through three agencies is carrying snippets nobody renders, CSS for sections that no longer exist, and assigns whose results are never printed.
Shopify ships the tool for this. Theme Check is described in Shopify’s documentation as “a linter for the Liquid and JSON inside your theme and theme app extensions”, and it detects syntax errors, missing templates, unused variables, unknown and deprecated tags, and performance issues. Two checks do most of the work at this stage:
OrphanedSnippet— “Identifies snippets that exist but are never referenced or rendered in the theme.” Every hit is a file you can probably delete outright.UnusedAssign— “Identifies variable definitions that aren’t used.” Individually trivial; in aggregate, the clearest signal of which templates have been edited by people who were afraid to remove anything.DeprecatedTagandDeprecatedFilter— the second is auto-correctable, which makes it the cheapest commit in the whole project.DeprecateLazysizes— “Discourages use of the lazysizes library for lazy loading images, iframes, and scripts.” A whole third-party library you may be able to drop for native attributes.
Make the linter a gate, not a report
Run shopify theme check --list first to see what is enabled, and --print to dump the resolved configuration. Then commit a .theme-check.yml at the root of the theme. It takes an extends setting with three documented presets — theme-check:all, theme-check:recommended and theme-check:theme-app-extension — and you can override individual check options or disable checks entirely.
The flag that turns this from a report into a gate is --fail-level, documented as the “minimum severity for exit with error code”. Set it to something your theme currently passes — not to the standard you want — and wire the command into CI. A gate at the level you already meet stops the theme getting worse while you improve it. A gate at the level you want is a red build on day one that everybody learns to ignore.
For the handful of genuine exceptions, the disable comments are per-file and per-line rather than per-repository: {% # theme-check-disable CheckName %} opens a disabled region, {% # theme-check-enable CheckName %} closes it, {% # theme-check-disable-next-line CheckName %} covers one line, and putting the disable comment on the first line of a file covers the file. Prefer those to loosening the config, because a disable comment sits next to the code it excuses and someone will read it.
--auto-correct (or -a) will “automatically fix offenses” where a check supports it. Run it on its own branch, review the diff in full, and do not combine it with hand edits — an auto-correct commit you can read in five minutes is worth more than one you have to reason about.
Stage two: consolidate the duplication you can prove
The second stage is where most refactors go wrong, because “duplication” is the easiest thing in the world to over-correct. Three product card variants that differ slightly is not obviously worse than one card snippet with eleven boolean parameters, and the parameterised version is harder for the next person to change safely.
The useful test is whether the duplicates have to change together. If a brand colour change means editing the same hex in four snippets, that is duplication worth removing and a settings value worth introducing. If three collection layouts happen to share markup but serve different merchandising intents, leave them alone — they will diverge again, and consolidating them just means the next divergence gets bolted on as a conditional.
Assets are the exception where consolidation nearly always pays. Theme Check has AssetSizeCSS and AssetSizeJavaScript checks that error when files exceed configured thresholds, ParserBlockingScript for “script tags that don’t have defer or async attributes”, and RemoteAsset, which “discourages use of third party domains for hosting assets”. Those four between them describe the loading behaviour of most slow themes, and none of the fixes changes a pixel.
Stage three: structure, and only where the roadmap is going
Restructuring is the expensive part — splitting a monolithic section into blocks, moving hardcoded content into settings, converting a template that predates JSON templates. It is also the part with the most benefit, because it changes what non-developers can do without you.
Do not do it everywhere. Refactoring a template that nobody will touch again produces exactly nothing; the return on structural work comes entirely from the changes it makes cheaper *afterwards*. So take the next two quarters of roadmap, list the templates it touches, and refactor those. If the roadmap does not touch a file, the file is fine as it is, however ugly. This is the single biggest saving available in a project like this, and it is a decision rather than a technique.
The honest version of this advice: if the roadmap touches almost every template, and the theme is old enough that the structural work is most of the effort anyway, you are not looking at a refactor. You are looking at a theme rebuild that keeps the design, and it is cheaper to plan it as one than to arrive at it six months in having paid for both.
Where the work lives while it is in progress
Use Shopify’s GitHub integration. A branch connects one-to-one with a theme, and the integration “updates your theme in the Shopify admin whenever the connected branch is updated”. So a refactor branch is an unpublished, previewable theme that the live store cannot see, and every step of the refactor is visible to a reviewer as a real page rather than a diff.
Two documented behaviours matter while a refactor is open. First, the sync runs both ways: when someone edits the theme through the admin — theme editor, code editor, or a theme app — Shopify commits those changes back to the connected branch. If a merchandiser is working in the published theme while you refactor a branch, you are both writing to the repository, and a long-lived refactor branch will drift from the live theme in ways you did not author.
Second, the conflict handling is not symmetrical with what developers expect. The theme editor warns a user that they are “overriding the new changes” when a file they have open has changed elsewhere, but Shopify’s documentation is explicit that “there are currently no conflict alerts in the code editor” and that the code editor’s version of a file overwrites the GitHub version. That is a good reason to keep refactor branches short and merge often, and a better reason to agree that during the refactor nobody edits theme code in the admin.
One more caveat worth knowing before you start rearranging branches: a branch cannot be reconnected to a theme after it has been disconnected — reconnecting creates a new theme instead.
What we would actually recommend
Most stores asking about a theme refactor should do stage one and stop for a month. Dead code removal plus the asset and script checks is a few days of work, needs no design input, and removes enough noise that you can tell whether the remaining problem is structural or was always just clutter. A surprising number of “unmaintainable” themes are maintainable once the files nobody uses are gone.
If after that the theme still fights every change, get the restructuring scoped against a real roadmap rather than against a standard. And if the answer comes back that most templates need structural work, take the rebuild — paying for an incremental refactor and then rebuilding anyway is the most expensive route to the same theme.
Questions this raises
How do you refactor a Shopify theme without breaking the live store?
Work on a branch connected to an unpublished theme through Shopify’s GitHub integration. The branch updates the theme automatically, so every step is previewable as a real page, and the published theme does not change until you publish. Keep the branch short-lived, because the integration also commits admin edits back to the branch and the code editor overwrites the GitHub version without a conflict alert.
What does Theme Check actually catch?
Shopify documents it as a linter for the Liquid and JSON in a theme, covering syntax errors, missing templates, unused variables, unknown and deprecated tags, and performance issues. For a refactor the most useful are `OrphanedSnippet` for snippets nothing renders, `UnusedAssign` for variables nothing uses, and the asset size and parser-blocking script checks.
Should a refactor change how the site looks?
No. The moment it does, it needs design review, stakeholder time and a slot in the calendar, and it becomes the change that gets blamed for the next dip in conversion. Keep visual changes in a separate, separately approved piece of work — and note the two or three places where the refactor genuinely cannot avoid a pixel difference so they can be checked deliberately.
Is it cheaper to refactor or to rebuild the theme?
It depends on how much of the theme your roadmap will touch. If it is a handful of templates, refactoring those is far cheaper. If it is most of them, a rebuild that keeps the existing design is usually cheaper than an incremental refactor that ends in a rebuild anyway. The decision is about scope of future change, not about the current state of the code.
Can Theme Check fix things automatically?
Some of them. The command takes `--auto-correct` (`-a`) to “automatically fix offenses”, and checks like `DeprecatedFilter` are documented as auto-correctable. Run it as its own commit on its own branch so the diff is reviewable, and do not mix hand edits into it.
How do you stop the theme getting worse while you improve it?
Commit a `.theme-check.yml`, run `shopify theme check` in CI, and set `--fail-level` to the severity your theme already passes. A gate set at the standard you currently meet blocks regressions from day one. A gate set at the standard you aspire to just produces a permanently red build that everyone stops reading.
NEXT STEP
Free store audit
A senior Shopify engineer reviews your storefront, theme performance and checkout, then sends a prioritised list of fixes.
