How to Document theme.json Changes So the Next Theme Update Doesn’t Wipe Them

What Actually Happens When a Theme Update Overwrites Your theme.json

You open the site on a Monday morning and the heading font is wrong. The custom color palette you built for the editorial team has reverted to default blues and grays. The wide-width block spacing that took three rounds of QA is gone. The root cause is almost always the same: a parent theme update replaced the theme.json file with a fresh copy from the developer, and nobody kept a record of what was changed or why. For a small-to-mid publishing team running a block theme, this is not a cosmetic glitch. It is a content-presentation failure that breaks the reading experience across every post.

theme.json is the central configuration file for WordPress block themes. It controls global styles, color palettes, typography scales, spacing presets, and block-level defaults. When a team modifies this file directly inside the parent theme directory, every edit becomes a liability. The next automatic or manual update will overwrite those changes without warning. The site will still load, but the visual identity will silently degrade. Editors will notice that the brand green is now a generic blue. The lead designer will ask why the body font reverted to the theme default. The answer is always the same: the documentation wasn’t there, and the override strategy wasn’t in place.

This article is a field manual for publishing teams that treat their WordPress installation as a product, not a project. It covers what to document, how to structure that documentation, where to store it, and how to make it survive staff turnover. The goal is to ensure that the next person who updates the theme—whether that’s you in six months or a new hire—can restore the custom theme.json settings without guesswork.

Why Direct theme.json Edits Are a Trap

Many teams start by editing the theme’s own theme.json file. It’s the fastest path: open the file, change the values, see the result in the Site Editor. The problem is that this file lives inside the theme directory, and theme updates replace the entire directory. Unless the theme is a custom build that will never receive an upstream update, those edits are temporary. Even with a child theme, the theme.json merging behavior in WordPress only supports additive changes for certain top-level keys like settings and styles. A child theme’s theme.json can override some values, but not all—and the rules for merging are not always intuitive.

I’ve seen teams lose months of design iteration because a single theme update wiped their typography scale. The developer who made the changes had moved on. There was no changelog, no backup, and no institutional memory of which values were custom. The fix took two weeks of reverse-engineering from screenshots. That’s the failure mode this documentation strategy prevents.

What to Document: The Minimum Viable Record

Documentation fails when it’s too ambitious. A 40-page style guide that nobody updates is worse than no guide at all. For theme.json changes, the record needs to be actionable, searchable, and close to the code. Here is the minimum set of fields every change entry should include:

  • Date of change: When was the override applied? This helps correlate with theme update logs.
  • Theme version at time of change: Critical for knowing whether an upstream update might have addressed the same setting.
  • JSON path: The exact path within theme.json, using dot notation (e.g., settings.color.palette).
  • Original value: What the parent theme shipped with. If unknown, note that.
  • Custom value: The full object or array that was inserted.
  • Reason for change: One sentence explaining the editorial or design requirement. Avoid vague notes like “branding.” Write “Marketing requested primary color match print palette #C8102E.”
  • Method of override: Child theme theme.json, code snippet in functions.php, or direct parent theme edit (with a warning).
  • Related issue or ticket: Link to the task where the change was requested, if available.

This record should live in a THEMEJSON-CHANGELOG.md file stored in the child theme’s root directory. Markdown is plain text, version-control friendly, and readable without special tools. If the team uses a wiki or internal documentation tool, the changelog can be mirrored there, but the canonical copy must be in the repository. Otherwise it will drift.

Where the Override Actually Belongs

Documentation is the safety net, but the best safety net is the one you don’t need. The ideal workflow is to avoid editing the parent theme’s theme.json entirely. WordPress 5.9+ supports a child theme’s theme.json that merges with the parent’s. For settings and styles, child-theme values take precedence. For customTemplates and templateParts, the child theme can add new items but cannot remove parent items. This merging behavior is documented on the WordPress Developer Resources site.

Here’s a practical example. Suppose the parent theme defines a color palette with a primary color of #2271b1. The editorial team’s brand guidelines require #c8102e. Instead of editing the parent theme.json, create a child theme and add a theme.json with only the override:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#c8102e",
          "name": "Primary"
        }
      ]
    }
  }
}

This child theme.json will merge with the parent’s and replace the primary color definition. The parent theme can update freely, and the override persists. The changelog file records why the override exists and who to ask if it needs to change again.

Handling Overrides That Child Themes Can’t Merge

Not everything in theme.json merges cleanly. The version field, for example, is a top-level integer that cannot be overridden by a child theme. If the parent theme uses version: 2 and the team needs to use a feature that requires version: 3, the child theme’s theme.json cannot force that change. The same limitation applies to $schema and certain block-level style variations.

In these cases, the team has two options. The first is to fork the parent theme and maintain a custom version. This is a last resort because it severs the update path. The second—and usually better—option is to use a small custom plugin that hooks into wp_theme_json_data_theme or wp_theme_json_data_user filters. These filters, introduced in WordPress 5.9, allow programmatic modification of the theme.json data before it’s processed. Here’s an example that forces the theme.json version to 3:

add_filter( 'wp_theme_json_data_theme', function( $theme_json ) {
    $data = $theme_json->get_data();
    $data['version'] = 3;
    $theme_json->update_with( $data );
    return $theme_json;
});

This code lives in a must-use plugin or a custom plugin that is part of the site’s core functionality. The changelog entry for this override should reference the plugin file and the specific filter, so the next developer can find it without grepping the entire codebase.

Documenting Global Styles Changes Made in the Site Editor

WordPress stores user-made global style changes in the database, in the wp_posts table as a custom post type called wp_global_styles. These changes are separate from the theme.json file and survive theme updates automatically. However, they create a different problem: the database becomes the source of truth for design tokens, and that truth is invisible to version control.

When an editor adjusts the site’s typography scale or color palette using the Site Editor, those changes are saved as a JSON blob in the database. If the site is ever migrated, cloned for staging, or restored from a backup, those database records must be preserved. If a developer resets global styles without realizing they contain critical overrides, the design reverts. The documentation strategy for this is to periodically export the global styles using the wp_theme_has_theme_json() function or by querying the wp_global_styles post type and saving the output to a file in the repository. This export should be dated and stored alongside the changelog.

For teams that want to avoid database-stored styles entirely, the alternative is to move all global style overrides into the child theme’s theme.json. This requires discipline: every design decision made in the Site Editor must be manually transcribed into the child theme’s theme.json file. The benefit is a single source of truth that is version-controlled. The cost is a slower design iteration loop. I recommend the child-theme approach for teams that have a defined design system and only use the Site Editor for minor tweaks.

Building a theme.json Restoration Runbook

Documentation is only useful if someone reads it at the right moment. The right moment is immediately after a theme update, when the site looks wrong. A restoration runbook is a short, step-by-step checklist stored in the same repository as the changelog. It should assume the reader is stressed and short on time. Here’s a template:

  1. Check the THEMEJSON-CHANGELOG.md file in the child theme root.
  2. Identify any entries marked with a date after the last known-good state.
  3. For each entry, verify whether the override is still present in the live site. Use the Site Editor’s Styles panel or inspect the database wp_global_styles post.
  4. If an override is missing, reapply it using the method specified in the changelog (child theme theme.json, filter, or direct edit with warning).
  5. After all overrides are restored, clear any full-page cache and verify the front-end rendering against the last known-good screenshots.
  6. Update the changelog with a new entry noting the theme update version and date, and confirm all overrides are intact.

This runbook should be stored as THEMEJSON-RESTORE.md in the same directory. It’s short enough to be read in a crisis and specific enough to prevent panic-driven mistakes.

Version-Controlled Screenshots as Visual Documentation

Text documentation captures the what and why. Screenshots capture the expected result. After every theme.json change that affects the front-end rendering, take a screenshot of a representative page. Store it in a docs/theme-screenshots/ directory with a filename that includes the date and a brief description: 2025-01-15-primary-palette-update.png. This gives the next person a visual reference to compare against after a theme update. If the heading color looks off, they can open the screenshot and see exactly what it should look like.

For teams using a visual regression testing tool, this step is automated. For everyone else, manual screenshots are better than nothing. The key is consistency: always use the same page, the same viewport width, and the same browser. I’ve used a pinned post titled “Style Reference – Do Not Delete” as the canonical screenshot target. It contains one of every core block, so a single screenshot captures the full design system.

Team collaborating on design documentation at a shared workspace
Design documentation is a team asset, not an individual’s memory.

Integrating the Changelog with Deployment Workflows

Documentation that requires manual effort will be skipped during a late-night deployment. The changelog should be part of the team’s existing workflow, not a separate task. If the team uses pull requests for theme changes, the PR template should include a checkbox: “Updated THEMEJSON-CHANGELOG.md with any theme.json overrides.” If the team deploys via CI/CD, a post-deployment script can diff the current theme.json against a stored baseline and alert if undocumented changes are detected.

Here’s a simple bash snippet that compares the active parent theme’s theme.json against a committed baseline and flags differences:

diff /wp-content/themes/parent-theme/theme.json /docs/baseline-theme.json > theme-diff.txt
if [ -s theme-diff.txt ]; then
  echo "WARNING: theme.json has changed. Check THEMEJSON-CHANGELOG.md."
fi

This kind of automated guardrail catches the problem before it reaches production. It’s not a replacement for human review, but it’s a reliable safety net for the 2 a.m. emergency update.

Training Editors to Recognize theme.json Drift

In a small-to-mid publishing team, the person who updates WordPress core and themes is often not the same person who manages the design system. It might be an IT generalist, a junior developer, or an editor with admin access. These team members need to know that a theme update can silently break the site’s appearance, and they need a clear protocol for what to do when it happens.

The training is simple: after every theme update, open the Style Reference page and compare it to the latest screenshot in the documentation directory. If anything looks different, do not ignore it. Follow the restoration runbook. If the runbook doesn’t solve the problem, escalate to the person listed in the changelog as the last modifier. This protocol should be written down and linked from the WordPress admin dashboard using a plugin like WP Help or a custom admin notice.

Person reviewing design specifications on a monitor with notes
Post-update review catches drift before readers notice.

When the Parent Theme Abandons theme.json

A less common but more dangerous scenario: the parent theme’s developer decides to move away from theme.json in a major update. They might switch to a PHP-based configuration, a proprietary options panel, or a different JSON structure. When this happens, the child theme’s theme.json overrides may silently stop working, or worse, cause PHP errors.

The changelog should include a section called “Parent Theme Compatibility Notes.” This section records the theme version range for which the documented overrides are known to work. If the parent theme releases a major version bump, the team should test the overrides in a staging environment before updating production. The compatibility notes should also list any deprecated keys or known conflicts. This is the kind of institutional knowledge that prevents a routine update from becoming a site outage.

FAQ

Can I use a child theme’s theme.json to override everything in the parent theme?

No. A child theme’s theme.json can override settings and styles at the top level, but it cannot override the version, $schema, or certain block-level properties that the parent theme defines as final. For those cases, use a custom plugin with the wp_theme_json_data_theme filter. Always test the merge behavior on a staging site before relying on it in production.

What’s the safest way to store custom CSS that supplements theme.json?

Custom CSS that cannot be expressed in theme.json should be added via the wp_add_inline_style function in a child theme’s functions.php or a custom plugin. Avoid adding CSS directly in the Customizer’s Additional CSS box if the site uses a block theme, because that CSS is stored in the database and can be lost during migrations. Document any custom CSS in the same changelog, noting which selectors it targets and why theme.json couldn’t handle it.

How do I export global styles from the database for version control?

You can query the wp_global_styles custom post type directly via WP-CLI or a small custom script. The post content is a JSON string containing all user-made global style changes. Export it with wp post get $(wp post list --post_type=wp_global_styles --format=ids) --field=post_content and save the output to a file in your repository. Run this export on a schedule or as part of your deployment process to keep the file current.

What if I’ve already lost my custom theme.json changes and have no documentation?

Start by checking if you have any backups of the parent theme directory from before the update. If you use version control, check the git history for the theme.json file. If you have a staging site that wasn’t updated, export its theme.json immediately. If none of these exist, you’ll need to reconstruct the changes from memory and screenshots. This is painful, which is why the documentation strategy in this article exists. Once you’ve reconstructed what you can, set up the changelog and child theme overrides so it doesn’t happen again. For broader site recovery tactics, see What to Fix First When a New WordPress Site Says Nothing Found.

Making This a Recurring Discipline

The difference between a team that gets burned once and a team that never gets burned is whether documentation becomes a habit. The changelog should be reviewed during sprint planning, mentioned in post-mortems, and treated as a living artifact of the design system. When a new team member joins, their first task should be to read the changelog and the restoration runbook, then make a small theme.json change and document it. This teaches the workflow and proves that the documentation is still accurate.

For publishing teams, the site’s visual consistency is directly tied to reader trust and advertising revenue. A broken design after a theme update isn’t just an inconvenience—it’s a business problem. The documentation practices described here cost a few minutes per change and save days of emergency work. They turn tribal knowledge into shared knowledge. And they ensure that the next theme update is a non-event, not a crisis.

Organized workspace with documentation and design references on a desk
Good documentation turns chaos into a repeatable process.