By Devport Team | Last updated: 2025-07-12 | 12 min read

What is theme.json? A Beginner's Guide to WordPress's Most Powerful File

If you've been exploring modern WordPress theme development, you've likely encountered references to a mysterious file called theme.json. This single file has revolutionized how we build and customize WordPress themes, yet many developers find it intimidating at first glance.

Think of theme.json as your theme's control center—a single configuration file that manages colors, typography, spacing, and virtually every visual aspect of your WordPress site. Instead of scattered PHP functions and CSS files, you now have one organized, powerful file that WordPress understands natively.

In this guide, we'll demystify theme.json and show you how this file can transform your WordPress development workflow, whether you're building themes or simply customizing your site.

Table of Contents

  1. What is theme.json and Why It Matters
  2. Basic Structure Walkthrough
  3. Common Settings Explained
  4. Your First theme.json Edits
  5. Troubleshooting Common Mistakes
  6. Visual theme.json Generator Tool

What is theme.json and Why It Matters

The Evolution of WordPress Theme Configuration

Before theme.json, WordPress theme configuration was scattered across multiple files: - Colors defined in CSS files - Typography set through custom functions - Spacing managed via the Customizer - Editor styles duplicated in separate stylesheets

This fragmentation led to: - Inconsistency: Editor styles didn't match frontend - Complexity: Multiple files to maintain - Performance issues: Redundant CSS loading - Limited control: Hard-coded values everywhere

Enter theme.json: The Game Changer

Introduced with WordPress 5.8, theme.json consolidates all theme configuration into a single, structured file. It's a JSON (JavaScript Object Notation) file that WordPress reads to understand your theme's design system.

Key Benefits: 1. Single Source of Truth: One file controls everything 2. Automatic CSS Generation: WordPress creates optimized styles 3. Editor Integration: Perfect sync between editor and frontend 4. No Code Duplication: Define once, use everywhere 5. Future-Proof: Built for Full Site Editing

Real-World Impact

Consider this simple color definition in theme.json:

{
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#0073aa",
          "name": "Primary Blue"
        }
      ]
    }
  }
}

This single configuration: - Creates a color option in the block editor - Generates CSS custom properties - Adds the color to all color pickers - Ensures consistency across your site - Requires zero additional CSS

Basic Structure Walkthrough

The Anatomy of theme.json

A theme.json file consists of several main sections, each serving a specific purpose:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    // Global and block-specific settings
  },
  "styles": {
    // Global and block-specific styles
  },
  "customTemplates": [
    // Custom page templates
  ],
  "templateParts": [
    // Reusable template parts
  ],
  "patterns": [
    // Block patterns to include
  ]
}

Understanding Each Section

1. $schema (Optional but Recommended)

"$schema": "https://schemas.wp.org/trunk/theme.json"

This enables intelligent code completion in VS Code and other editors. It's like having WordPress documentation built into your editor!

2. version

"version": 2

Currently, version 2 is the latest. This ensures WordPress interprets your configuration correctly.

3. settings

The settings section defines what options are available in the editor:

"settings": {
  "color": {
    "custom": true,
    "palette": []
  },
  "typography": {
    "fontSizes": []
  },
  "spacing": {
    "units": ["px", "rem", "em", "%"]
  }
}

4. styles

The styles section sets default values for your theme:

"styles": {
  "color": {
    "background": "#ffffff",
    "text": "#000000"
  },
  "typography": {
    "fontSize": "16px",
    "lineHeight": "1.6"
  }
}

Hierarchy and Inheritance

theme.json follows a logical hierarchy: 1. Global settings apply site-wide 2. Block-specific settings override globals 3. User customizations override everything

Example hierarchy:

{
  "settings": {
    "color": {
      "custom": true  // Global setting
    },
    "blocks": {
      "core/button": {
        "color": {
          "custom": false  // Override for buttons only
        }
      }
    }
  }
}

Common Settings Explained

Color Configuration

Colors are one of the most powerful features in theme.json:

{
  "settings": {
    "color": {
      "custom": true,           // Allow custom colors
      "customDuotone": true,    // Allow custom duotone filters
      "customGradient": true,   // Allow custom gradients
      "defaultPalette": false,  // Disable WordPress default colors
      "palette": [
        {
          "slug": "primary",
          "color": "#0073aa",
          "name": "Primary"
        },
        {
          "slug": "secondary",
          "color": "#005177",
          "name": "Secondary"
        },
        {
          "slug": "accent",
          "color": "#d63638",
          "name": "Accent"
        },
        {
          "slug": "background",
          "color": "#f7f7f7",
          "name": "Background"
        },
        {
          "slug": "foreground",
          "color": "#333333",
          "name": "Foreground"
        }
      ],
      "gradients": [
        {
          "slug": "primary-to-secondary",
          "gradient": "linear-gradient(135deg, var(--wp--preset--color--primary) 0%, var(--wp--preset--color--secondary) 100%)",
          "name": "Primary to Secondary"
        }
      ],
      "duotone": [
        {
          "slug": "blue-orange",
          "colors": ["#0073aa", "#ff6900"],
          "name": "Blue and Orange"
        }
      ]
    }
  }
}

What This Creates: - Color swatches in every color picker - CSS custom properties like --wp--preset--color--primary - Gradient options in supported blocks - Duotone filters for images

Typography System

Typography settings control fonts, sizes, and text appearance:

{
  "settings": {
    "typography": {
      "customFontSize": true,
      "fontFamilies": [
        {
          "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
          "slug": "system",
          "name": "System Font"
        },
        {
          "fontFamily": "'Inter', sans-serif",
          "slug": "inter",
          "name": "Inter",
          "fontFace": [
            {
              "fontFamily": "Inter",
              "fontWeight": "400",
              "fontStyle": "normal",
              "src": ["file:./assets/fonts/inter-regular.woff2"]
            },
            {
              "fontFamily": "Inter",
              "fontWeight": "700",
              "fontStyle": "normal",
              "src": ["file:./assets/fonts/inter-bold.woff2"]
            }
          ]
        }
      ],
      "fontSizes": [
        {
          "slug": "small",
          "size": "0.875rem",
          "name": "Small"
        },
        {
          "slug": "medium",
          "size": "1.125rem",
          "name": "Medium"
        },
        {
          "slug": "large",
          "size": "1.75rem",
          "name": "Large"
        },
        {
          "slug": "x-large",
          "size": "2.25rem",
          "name": "Extra Large"
        }
      ]
    }
  }
}

Spacing and Layout

Control spacing throughout your theme:

{
  "settings": {
    "spacing": {
      "padding": true,
      "margin": true,
      "blockGap": true,
      "units": ["px", "em", "rem", "%", "vw", "vh"],
      "spacingScale": {
        "steps": 7,
        "increment": 1.5,
        "mediumStep": 1.5
      }
    },
    "layout": {
      "contentSize": "720px",
      "wideSize": "1200px"
    }
  }
}

Appearance Tools

Enable UI controls in the editor:

{
  "settings": {
    "appearanceTools": true,  // Enables all tools below
    "border": {
      "color": true,
      "radius": true,
      "style": true,
      "width": true
    }
  }
}

Your First theme.json Edits

Step 1: Create the File

  1. Navigate to your theme's root directory
  2. Create a new file named theme.json
  3. Add the basic structure:
{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {},
  "styles": {}
}

Step 2: Add a Color Palette

Let's create a simple color system:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "black",
          "color": "#000000",
          "name": "Black"
        },
        {
          "slug": "white",
          "color": "#ffffff",
          "name": "White"
        },
        {
          "slug": "primary",
          "color": "#007cba",
          "name": "Primary"
        }
      ]
    }
  }
}

Step 3: Define Typography

Add font sizes to your configuration:

{
  "settings": {
    "typography": {
      "fontSizes": [
        {
          "slug": "small",
          "size": "13px",
          "name": "Small"
        },
        {
          "slug": "normal",
          "size": "16px",
          "name": "Normal"
        },
        {
          "slug": "large",
          "size": "24px",
          "name": "Large"
        }
      ]
    }
  }
}

Step 4: Set Global Styles

Apply default styles to your theme:

{
  "styles": {
    "color": {
      "background": "var(--wp--preset--color--white)",
      "text": "var(--wp--preset--color--black)"
    },
    "typography": {
      "fontSize": "var(--wp--preset--font-size--normal)",
      "lineHeight": "1.6"
    },
    "elements": {
      "link": {
        "color": {
          "text": "var(--wp--preset--color--primary)"
        }
      }
    }
  }
}

Step 5: Customize Specific Blocks

Target individual blocks with specific settings:

{
  "styles": {
    "blocks": {
      "core/button": {
        "color": {
          "background": "var(--wp--preset--color--primary)",
          "text": "var(--wp--preset--color--white)"
        },
        "border": {
          "radius": "4px"
        }
      },
      "core/quote": {
        "border": {
          "left": {
            "color": "var(--wp--preset--color--primary)",
            "style": "solid",
            "width": "4px"
          }
        },
        "spacing": {
          "padding": {
            "left": "20px"
          }
        }
      }
    }
  }
}

Troubleshooting Common Mistakes

1. Invalid JSON Syntax

Problem: WordPress ignores your theme.json

{
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#007cba"
          "name": "Primary"  // Missing comma!
        }
      ]
    }
  }
}

Solution: Use a JSON validator or VS Code with the schema URL

2. Incorrect Property Names

Problem: Settings don't apply

{
  "settings": {
    "colors": {  // Should be "color" (singular)
      "palette": []
    }
  }
}

Solution: Check the official schema for correct property names

3. Missing Version Number

Problem: Unexpected behavior

{
  "settings": {},  // Missing version!
  "styles": {}
}

Solution: Always include "version": 2

4. Conflicting Settings

Problem: Block settings override global settings unexpectedly

{
  "settings": {
    "color": {
      "custom": true  // Global: custom colors allowed
    },
    "blocks": {
      "core/paragraph": {
        "color": {
          "custom": false  // Paragraphs: no custom colors
        }
      }
    }
  }
}

Solution: Understand the hierarchy and test thoroughly

5. Path Issues with Assets

Problem: Fonts or images don't load

{
  "settings": {
    "typography": {
      "fontFamilies": [{
        "fontFace": [{
          "src": ["./assets/fonts/custom.woff2"]  // Should be "file:./assets/fonts/custom.woff2"
        }]
      }]
    }
  }
}

Solution: Use file: protocol for local assets

Common Error Messages

Error Cause Solution
"theme.json is invalid" JSON syntax error Validate JSON structure
Styles not applying Incorrect selectors Check property names
Colors missing in editor Schema mismatch Update to version 2
Custom fonts not loading Path issues Use file: protocol

Visual theme.json Generator Tool

Online Tools

Several visual tools can help you generate theme.json configurations:

  1. Theme.json Generator
  2. Visual interface for all settings
  3. Live preview
  4. Export ready-to-use code

  5. WordPress Theme JSON Generator

  6. Focused on typography and colors
  7. Preset templates
  8. Import existing theme.json

  9. Create Block Theme Plugin

  10. WordPress admin interface
  11. Visual editing
  12. Direct theme integration

Using the Create Block Theme Plugin

  1. Install the Plugin Plugins → Add New → Search "Create Block Theme" → Install & Activate

  2. Access the Interface Appearance → Create Block Theme

  3. Visual Editing Options

  4. Colors: Pick and organize palette
  5. Typography: Set font families and sizes
  6. Spacing: Configure padding and margins
  7. Export: Download your theme.json

Building Your Own Configuration

Here's a complete starter theme.json template:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "color": {
      "custom": true,
      "customDuotone": true,
      "customGradient": true,
      "defaultPalette": false,
      "palette": [
        {
          "slug": "primary",
          "color": "#0073aa",
          "name": "Primary"
        },
        {
          "slug": "secondary",
          "color": "#005177",
          "name": "Secondary"
        },
        {
          "slug": "foreground",
          "color": "#333333",
          "name": "Foreground"
        },
        {
          "slug": "background",
          "color": "#ffffff",
          "name": "Background"
        },
        {
          "slug": "accent",
          "color": "#e65100",
          "name": "Accent"
        }
      ]
    },
    "typography": {
      "customFontSize": true,
      "fontFamilies": [
        {
          "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
          "slug": "system-font",
          "name": "System Font"
        }
      ],
      "fontSizes": [
        {
          "slug": "small",
          "size": "clamp(0.875rem, 2vw, 1rem)",
          "name": "Small"
        },
        {
          "slug": "medium",
          "size": "clamp(1rem, 2.5vw, 1.25rem)",
          "name": "Medium"
        },
        {
          "slug": "large",
          "size": "clamp(1.75rem, 3vw, 2.25rem)",
          "name": "Large"
        },
        {
          "slug": "x-large",
          "size": "clamp(2.5rem, 4vw, 3.5rem)",
          "name": "Extra Large"
        }
      ]
    },
    "spacing": {
      "padding": true,
      "margin": true,
      "units": ["px", "em", "rem", "%", "vw", "vh"]
    },
    "layout": {
      "contentSize": "650px",
      "wideSize": "1200px"
    }
  },
  "styles": {
    "color": {
      "background": "var(--wp--preset--color--background)",
      "text": "var(--wp--preset--color--foreground)"
    },
    "typography": {
      "fontFamily": "var(--wp--preset--font-family--system-font)",
      "fontSize": "var(--wp--preset--font-size--medium)",
      "lineHeight": "1.6"
    },
    "spacing": {
      "blockGap": "1.5rem"
    },
    "elements": {
      "link": {
        "color": {
          "text": "var(--wp--preset--color--primary)"
        },
        ":hover": {
          "color": {
            "text": "var(--wp--preset--color--secondary)"
          }
        }
      },
      "button": {
        "border": {
          "radius": "4px"
        },
        "color": {
          "background": "var(--wp--preset--color--primary)",
          "text": "var(--wp--preset--color--background)"
        },
        ":hover": {
          "color": {
            "background": "var(--wp--preset--color--secondary)"
          }
        }
      }
    }
  }
}

Next Steps

Now that you understand theme.json, you're ready to:

  1. Experiment: Try modifying an existing theme's theme.json
  2. Build: Create your own block theme from scratch
  3. Learn More: Explore advanced features like custom CSS properties
  4. Share: Contribute to the WordPress community

Resources for Continued Learning

Join the Community

Conclusion

The theme.json file represents a paradigm shift in WordPress theme development. By centralizing configuration, it simplifies development while providing unprecedented control over your site's appearance.

Start small—add a color palette, define some font sizes, and gradually explore more advanced features. Remember, every expert was once a beginner, and the WordPress community is here to help you succeed.

Whether you're building the next great WordPress theme or simply customizing your site, theme.json puts the power in your hands. Welcome to the future of WordPress theming!


Want to dive deeper into WordPress development? Check out our comprehensive Ultimate Guide to Gutenberg and Full-Site Editing for more advanced techniques and best practices.