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
- What is theme.json and Why It Matters
- Basic Structure Walkthrough
- Common Settings Explained
- Your First theme.json Edits
- Troubleshooting Common Mistakes
- 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
- Navigate to your theme's root directory
- Create a new file named
theme.json
- 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:
- Theme.json Generator
- Visual interface for all settings
- Live preview
-
Export ready-to-use code
- Focused on typography and colors
- Preset templates
-
Import existing theme.json
- WordPress admin interface
- Visual editing
- Direct theme integration
Using the Create Block Theme Plugin
-
Install the Plugin
Plugins → Add New → Search "Create Block Theme" → Install & Activate
-
Access the Interface
Appearance → Create Block Theme
-
Visual Editing Options
- Colors: Pick and organize palette
- Typography: Set font families and sizes
- Spacing: Configure padding and margins
- 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:
- Experiment: Try modifying an existing theme's theme.json
- Build: Create your own block theme from scratch
- Learn More: Explore advanced features like custom CSS properties
- Share: Contribute to the WordPress community
Resources for Continued Learning
Join the Community
- WordPress Slack: Join #core-editor channel
- GitHub Discussions: Participate in Gutenberg development
- Local Meetups: Find WordPress developers near you
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.