How to Document theme.json Changes So the Next WordPress Update Doesn’t Undo Them

The Real Problem: theme.json Is a Living File, Not a Set-It-and-Forget-It Config

For a small-to-mid publishing team running a block-based WordPress site, theme.json ends up carrying a lot of weight. It’s where global styles, color palettes, type scales, spacing presets, and block-level settings all get defined. The headache isn’t writing valid JSON—it’s that three different forces keep tugging at the same file: the original theme developer, the site admin clicking around in the Global Styles interface, and the engineer who drops in manual overrides. Without a tight documentation habit, a routine theme update will quietly steamroll your custom theme.json values. Suddenly, the visual hierarchy is off, that carefully chosen font pairing is gone, or block supports the editorial staff depends on have reverted. This article lays out a documentation method that treats theme.json as a versioned artifact—not a throwaway config file—so your next update doesn’t trash months of design decisions.

The core tension is simple: WordPress’s Global Styles UI writes straight to the database, while the theme’s theme.json sits on the file system. When a theme update replaces that file, any manual edits you made to it disappear. The UI-saved styles survive in the database, but they can clash with the new theme’s defaults. The fix is a disciplined diff-and-merge workflow paired with a living changelog that tracks every intentional deviation from the upstream theme. This isn’t about dodging updates. It’s about making them boring and predictable.

Why theme.json Breaks Silently After an Update

The WordPress Global Styles system merges settings from three layers: core defaults, the theme’s theme.json, and user customizations stored in the wp_global_styles post. When you edit theme.json directly—adding a custom font size, killing a color palette, or locking down block spacing—you’re poking the middle layer. A theme update replaces that file wholesale. If your changes weren’t captured somewhere else, they’re just gone. The database layer won’t save you here; it only holds overrides made through the UI, not manual JSON edits. The result is a site that looks subtly wrong: wrong line heights, missing duotone filters, busted layout widths. The editorial team notices first, usually right before a big publish.

The Three-Layer Cascade and Where Your Edits Die

WordPress resolves styles by merging core defaults, the theme’s theme.json, and user customizations. The cascade runs: core → theme → user. If you add a custom color palette directly to the theme’s theme.json, it lives in the theme layer. A theme update that ships a new theme.json will replace your file entirely, and your palette vanishes. The user layer—populated via the Global Styles UI—survives updates, but it can’t hold everything. For example, you can’t add a new fontSize preset through the UI; that requires a JSON edit. Your documentation has to distinguish between what lives in the theme layer, what lives in the user layer, and what falls into the gap.

Building a theme.json Change Log That Actually Works

A change log isn’t a commit message. It’s a structured record that lets you reapply customizations after an update without re-deriving every decision. For each modification to theme.json, record five fields: the date of the change, the exact JSON path affected (e.g., settings.color.palette[4]), the previous value, the new value, and a rationale tied to a business or editorial requirement. Store this log in the theme’s root directory as CHANGELOG-theme.json.md. When a theme update lands, you diff the new upstream theme.json against your modified version, spot conflicts, and use the changelog to decide which customizations to reapply. This turns a panic-inducing merge into a checklist.

Example entry:

## 2025-03-12
### settings.typography.fontSizes
- Added custom size "article-body" (18px) to match print edition body text.
- Rationale: Editorial team requires consistent 18px body across all article templates; default theme sizes don't include this value.
- Previous: [default theme array]
- New: [default array + {"slug":"article-body","size":"18px","name":"Article Body"}]

Separating Design Tokens from Theme Overrides

A common failure mode is mixing two types of theme.json changes: design tokens (colors, fonts, spacing) and structural overrides (block supports, template part areas, custom templates). Design tokens are portable; they define the visual language. Structural overrides are theme-specific and fragile. Document them in separate sections of your changelog. Better yet, extract design tokens into a child theme’s theme.json where possible, though this only works if the parent theme supports partial token merging. Most don’t, so the changelog becomes your child theme by proxy.

Capturing the Intent Behind Each Edit

The most dangerous theme.json changes are the ones made six months ago by a developer who’s since left the team. Without context, a future maintainer will either preserve the edit out of fear or delete it out of frustration. Each entry in the changelog must answer: “What editorial or design constraint made this necessary?” For example, “Increased settings.layout.contentSize to 800px because the editorial team’s long-form articles require a wider reading line for readability, and the default 650px caused excessive line breaks in code blocks.” This ties the technical change to a measurable editorial outcome, which is the only justification that survives staff turnover.

Two professionals reviewing a printed document layout, representing the editorial review process for theme.json changes

Versioning theme.json with Your Theme (or Against It)

If you’re using a custom theme, you control the update cycle. In that case, treat theme.json like any other source file: version it in Git alongside your PHP templates, and use a build step to merge upstream changes from the parent theme if you’re using a child theme. The real pain comes with third-party themes that update frequently. For those, maintain a separate theme-changes.json file that stores only your deltas. After each update, run a script (or a manual diff) that applies your deltas to the new theme.json. This is not a plugin; it’s a workflow. The script can be as simple as a Node.js file that uses json-merge-patch or a PHP script that runs wp theme update and then patches the file. The key is that the delta file is human-readable and version-controlled, so you can see exactly what you’re injecting and why.

Close-up of a developer editing a JSON configuration file on a laptop screen

Preventing the Global Styles UI from Nuking Your Manual Edits

The Global Styles interface in the Site Editor is a double-edged tool. It lets editors tweak typography and colors without touching code, but it writes those changes to the database, creating a user-layer override that can mask or conflict with your theme.json settings. If you’ve manually set a default palette in theme.json and an editor later changes a color via the UI, the database value wins. The next theme update might reset the UI, or it might not—the behavior depends on how the theme handles styles vs. settings. To avoid this, lock down the settings you consider non-negotiable by using the settings.xxx.default property where supported, and explicitly document which settings editors are allowed to modify via the UI. If a setting must never be changed, consider removing it from the UI entirely by filtering theme.json with the wp_theme_json_data_theme hook, but document that filter as part of the theme.json changelog.

Using a Child Theme to Absorb Custom Styles

A child theme’s theme.json can override or extend the parent’s settings, but only for certain top-level keys: settings, styles, and templateParts. This is the cleanest way to preserve custom design tokens across parent theme updates, because the child theme’s file is never touched by the update process. However, child themes cannot override version or $schema, and they cannot remove settings the parent declares—only add or override. If your customization requires removing a parent’s default color palette, you’ll need to either use a filter or maintain a full theme.json copy. Document which approach you chose and why, so the next person doesn’t waste hours trying to make a child theme do something it can’t.

Creating a Pre-Update Audit Checklist

Before applying any theme update, run through a checklist that verifies your customizations are accounted for. The checklist should include: (1) diff the new theme’s theme.json against the previous version to identify upstream changes; (2) cross-reference those changes against your changelog to flag potential conflicts; (3) if using a child theme, verify that your child’s theme.json still correctly overrides the parent’s new defaults; (4) if using manual edits, apply your delta file to the new theme.json and validate the result with a JSON schema validator; (5) test the patched theme on a staging environment, specifically checking the editor UI, front-end rendering, and any block patterns that rely on custom presets. This checklist should live in the theme’s documentation folder, not in someone’s head.

A team of editors and developers reviewing a website layout on a large monitor during a theme update meeting

FAQ: theme.json Documentation for Publishing Teams

What’s the fastest way to recover lost theme.json changes after a botched update?

If you didn’t keep a changelog, your best fallback is the database. Query the wp_postmeta table for the previous theme’s stylesheet name, then look in wp_posts for the wp_global_styles post type associated with that theme. That post contains a serialized version of the user customizations made via the Global Styles UI—not your manual file edits, but it’s a starting point. For manual edits, you’ll need to restore the old theme.json from backups or version control. If neither exists, you’re rebuilding from memory, which is why the changelog is non-negotiable.

How do I know if a setting should go in theme.json or be registered via PHP?

Use theme.json for anything that defines the default visual presentation: color palettes, font sizes, spacing scales, block supports, and template parts. Use PHP registration (via add_theme_support or block-specific hooks) for settings that must be enforced regardless of the theme’s JSON, such as removing core block patterns or disabling custom font sizes site-wide. PHP registrations survive theme updates because they live in your child theme or custom plugin. Document both in the same changelog, noting the registration method and the file where it lives.

Can I automate the merge process for theme.json updates?

Yes, but only if your customizations are structured as a JSON Merge Patch (RFC 7396). Store your deltas in a separate file, then use a tool like json-merge-patch (Node.js) or a custom WP-CLI command to apply them after the update. The automation is straightforward; the hard part is maintaining the delta file so it accurately reflects your intent. If your delta file says “set settings.color.palette to this array,” it will replace the entire palette, not merge individual colors. You need to decide whether you’re replacing or merging each top-level key, and document that strategy.

What’s the connection between theme.json documentation and the “Nothing Found” error?

A corrupted or missing theme.json can cause template resolution failures that manifest as “Nothing Found” on archive or singular pages. If your theme relies on theme.json to register custom templates or template parts, and an update removes those registrations, WordPress may fall back to the index template incorrectly. We covered template resolution debugging in detail in What to Fix First When a New WordPress Site Says Nothing Found. The same diagnostic approach applies: check which templates are registered, verify the query matches, and confirm your theme.json is intact.