To update our customized Shopify Horizon theme without losing code changes, we combined Shopify's official update draft, Git history, and a Codex-assisted three-way audit—then verified the result through storefront QA.
CheckoutWorks runs on Shopify, and our own storefront uses Horizon. Our update from 4.1.4 to 4.1.5 became the first full test of this workflow: what Shopify transferred, what Codex helped us migrate, what QA still caught, and what we will repeat next time.
Why we keep our Horizon theme current
Shopify theme updates can include new features, design improvements, and bug fixes. Some newer features also depend on updated theme architecture, so an existing theme does not automatically gain everything Shopify releases.
Shopify describes Horizon as its flagship first-party theme, built around current Liquid storefront features. Staying reasonably current lets our own site benefit from Shopify's ongoing work without giving up the parts of the storefront we have deliberately customized.
The trade-off is simple: every custom edit can make the next update harder. Our goal is therefore not zero custom code. It is custom code that is easy to identify, review, test, and carry forward.
How we make our customizations easier to carry forward
For our own theme, we follow a native-first order:
- Use a native Shopify or Horizon feature when it meets the requirement, such as the dynamic sources behind our storefront FAQs from Shopify Knowledge Base.
- Use Theme Editor settings or Custom Liquid for small, modular additions, such as our country-aware size chart.
- Add custom theme code only when the native options are not enough, such as our variant button badges, which live in one snippet with two small render calls in Horizon's files, or our block that hides content on mobile or desktop, which is a single new theme block file with no edits to Horizon's own files.
When custom code is necessary, we try to keep related changes together. Store-specific CSS lives in a dedicated stylesheet where practical. Modified Liquid and CSS regions include a nearby Modified by CheckoutWorks.dev comment. Git records the history behind each change, including older work that predates the comment convention.
These habits do not make an update automatic. They make the evidence easier for both a developer and Codex to inspect.
Step 1: Start with Shopify's official theme update
We first used the update offered in Shopify Admin. Shopify's documented process adds the new version as a draft, so the live storefront remains unchanged while the update is reviewed. Theme Editor settings, layouts, section and block settings, templates, app embeds, and theme-content wording are copied to the updated theme. Non-conflicting code edits can also be included.
We treated JSON templates and config/settings_data.json separately as Theme Editor state rather than ordinary code edits, as described in Step 4.
Shopify offered Horizon 4.1.5 as an update to our 4.1.4 theme.
This official draft is the right starting point because it preserves the new theme's structure. Copying old files wholesale into it could silently replace official fixes or newer implementations with older code.
The existing live theme stayed active while the 4.1.5 update remained a separate draft.
Step 2: Keep the update states separate
Before migrating code, we preserved distinct reference points:
- The current live theme.
- The untouched Shopify-generated update draft.
- A working QA copy of the updated theme.
- The previous live theme as a rollback option.
- Git history and local theme snapshots for detailed comparison.
The exact names matter less than making each role obvious. A name such as Horizon 4.1.5 — Shopify Update Baseline should never be confused with Horizon 4.1.5 — QA or the current live theme.
We keep the current live version, the untouched update baseline, the QA draft, and the previous live rollback until the new theme has been published and monitored. Older development drafts do not need to stay in Shopify forever when their history is safely preserved in Git.
When this level of review is useful
For an almost-unmodified Horizon theme, Shopify's built-in updater may be enough. The three-way workflow becomes more useful when the live theme contains custom Liquid, CSS, JavaScript, app-generated code, or older changes that were never documented.
Step 3: Let Codex build the customization inventory
Codex is not required to update Horizon. We used it to speed up the audit and migration of our existing customizations. Before editing anything, we asked Codex to plan a three-way review rather than make a simple "old versus new" comparison:
- The original, unmodified Horizon 4.1.4 baseline.
- Our customized CheckoutWorks Horizon 4.1.4 live theme.
- The Shopify-generated Horizon 4.1.5 draft.
The initial Codex plan separated the official baseline, the customized theme, and the new target.
The audit identified 15 code files that needed detailed review. Thirteen already had our customization marker. Two more had no marker, but Git history confirmed that they contained store-specific work. Codex also found three standalone custom files that Shopify's update had already preserved, so they did not need to be copied again.
The audit grouped custom code, Theme Editor data, content changes, and official Horizon changes separately.
This inventory prevented two common mistakes: missing an old customization because it lacked a comment, and reapplying a customization that Shopify had already transferred.
Step 4: Migrate the intent, not the old files
For every customization, we asked what behavior it was meant to preserve. Then we reapplied that behavior to Horizon 4.1.5 using the new version's structure.
Small, isolated changes could be moved directly. Files that Shopify had changed substantially needed a new implementation. JSON templates and settings_data.json were reviewed as Theme Editor state rather than overwritten as complete files.
Nearby attribution comments make custom regions easier to locate during the next update.
We also had Codex generate or restore comments around modified code regions. Comments are not a replacement for Git, but they provide an immediate signal when someone opens a theme file months later.
Why we chose the three-way audit
| Approach | What it preserves | Main trade-off |
|---|---|---|
| Copy old theme files over the update | Old custom code | Can replace newer Horizon fixes or architecture with older code |
| Use Shopify's official update only | Official changes plus transferable settings and code | Conflicts and undocumented edits can still be missed |
| Use the official draft with Git and a Codex three-way audit | Official changes plus reviewed customizations | More QA, but it gave us the clearest migration path |
Step 5: What the code audit missed
A clean code comparison is not proof that the storefront still looks and behaves correctly. Our QA found a button font-weight customization that existed in the live theme but was absent from the new draft. It was older than our reliable marker convention, so a comment-only audit could have missed it.
Before: The updated draft used the lighter default button weight.
After: The intended heading weight was restored and rechecked.
This was a useful reminder: AI can trace files and history quickly, but visual QA catches behavior that code metadata cannot fully describe.
If you notice something missing only after an update is live, our guide to finding and restoring customizations lost in a Shopify theme update covers where to look and how to bring each one back.
Step 6: Validate before publishing
We ran Shopify Theme Check across the completed theme. It inspected 366 files and returned zero errors. Two known OrphanedSnippet warnings remained for snippets called dynamically through Custom Liquid. Static analysis cannot see those runtime references, so we verified both snippets in the storefront instead of deleting them.
Theme Check completed with zero errors and two understood warnings.
We also reviewed the main storefront routes on desktop and mobile, tested key product and cart interactions, opened the Theme Editor, and checked that sections and blocks could still be saved. Custom CSS selectors received extra attention because selectors from an older theme version might no longer exist after an update.
Step 7: Publish with a rollback path
Only after the code audit, visual review, interaction testing, and Theme Check did the 4.1.5 draft become the new active theme. The previous live theme stayed available as a short-term rollback, while Git retained the durable history.
Horizon 4.1.5 became active after the migration and QA were complete.
What we will repeat with every Horizon update
- Prefer native Shopify features and keep custom code focused.
- Mark custom code regions and preserve history in Git.
- Use Shopify's official update to create the new draft.
- Keep the live theme, update baseline, QA draft, and rollback copy distinct.
- Use Codex to inventory changes with comments, Git history, and three-way comparison.
- Reapply customization intent without overwriting the new theme's foundation.
- Run Theme Check and test the actual storefront and Theme Editor.
- Publish only after the new draft passes QA.
The main lesson was that Codex worked best as an audit and implementation partner, not as a one-click updater. Shopify supplied the new foundation. Git supplied the history. Codex helped us connect the evidence and reapply the intended behavior. Storefront QA decided whether the result was actually ready.
That combination gives us a practical way to keep our own Horizon theme updated while retaining the storefront details we intentionally built. The next release should begin with a cleaner inventory, clearer markers, and fewer surprises than this one.