How to Create a WordPress Block Theme From Scratch
Learn how to create a WordPress block theme from scratch. Master theme.json settings, HTML block templates, custom patterns, and global styling variations.
WordPress development has fundamentally shifted away from PHP-heavy template hierarchies toward Full Site Editing and modular block themes. By relying on declarative configuration through theme.json and semantic HTML block markup, modern WordPress themes offer superior performance, direct visual customization, and clean codebases. Building a block theme from scratch gives developers granular control over design tokens and editor ergonomics without relying on cumbersome visual page builders.
Block Themes vs Classic PHP Themes: The Architectural Shift
For almost two decades, creating a WordPress theme meant assembling a maze of PHP template files—header.php, index.php, single.php, and footer.php—interleaved with template tags, custom action hooks, and heavy CSS stylesheets. While functional, classic themes fragmented site styling between customizer options, CSS stylesheets, and shortcodes.
Block themes replace this paradigm with declarative data structures and Full Site Editing (FSE). Instead of executing server-side PHP loops to render post content, the core engine parses semantic HTML block comments directly in the editor and on the front end.
| Architectural Dimension | Classic WordPress Theme | Modern Block Theme (FSE) |
|---|---|---|
| Primary File Format | PHP template files (.php) |
HTML block markup files (.html) |
| Design System Configuration | Custom CSS, Customizer API, Sass | Centralized declarative theme.json |
| Header / Footer Architecture | header.php, get_header() |
Modular block template parts (parts/*.html) |
| Visual Customization | Theme Customizer or external page builders | Native Gutenberg Site Editor |
| Front-End Performance | Often loads unused CSS across all routes | Enqueues block CSS selectively per page |
| Component Reusability | PHP template parts or custom shortcodes | Composable Block Patterns & Synced Patterns |
Understanding this architectural shift is essential. When you audit modern WordPress templates, you will find that the best starters prioritize lightweight block scaffolding over monolithic PHP logic.
The Minimal File Structure for a WordPress Block Theme
Starting a custom block theme requires fewer files than you might anticipate. At its core, WordPress only requires two mandatory files to recognize a block theme, though a practical production theme incorporates a clean folder hierarchy:
my-custom-theme/
├── style.css # Theme metadata and non-block custom styles
├── theme.json # Central design tokens, presets, and block styling
├── functions.php # Optional theme setup, pattern registration, enqueue hooks
├── templates/
│ ├── index.html # Fallback master template
│ ├── single.html # Individual blog post layout
│ ├── page.html # Standard static page layout
│ └── 404.html # Not found template
└── parts/
├── header.html # Global navigation bar
└── footer.html # Global site footer
The style.css file serves as the theme identity descriptor. WordPress parses the comment block at the top:
/*
Theme Name: Custom Block Engine
Theme URI: https://example.com/theme
Author: Engineering Team
Version: 1.0.0
Description: High-performance, clean WordPress block theme built for speed.
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.1
Text Domain: custom-block-engine
*/
No CSS rules are strictly needed in style.css if you configure your design tokens within theme.json.
Configuring the Design System with theme.json
The theme.json file is the heart of any modern block theme. It standardizes typography scales, color palettes, layout widths, and spacing presets into native CSS custom properties automatically managed by WordPress.
Here is a focused configuration demonstrating core design system controls:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
"layout": {
"contentSize": "800px",
"wideSize": "1200px"
},
"color": {
"palette": [
{ "slug": "base", "color": "#ffffff", "name": "Base" },
{ "slug": "contrast", "color": "#111827", "name": "Contrast" },
{ "slug": "primary", "color": "#2563eb", "name": "Primary Accent" },
{ "slug": "muted", "color": "#6b7280", "name": "Muted Text" }
]
},
"typography": {
"fontFamilies": [
{
"fontFamily": "Inter, sans-serif",
"slug": "body",
"name": "Body Font"
}
]
}
}
}
By enabling "appearanceTools": true, you automatically activate margins, paddings, border radius, and typography line-height controls across all blocks in the visual Site Editor.
Authoring HTML Block Templates and Template Parts
Templates in a block theme are written using HTML comments that Gutenberg interprets as blocks. Rather than writing PHP loops, you define structural blocks directly inside templates/index.html:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:query {"queryId":1,"query":{"perPage":10,"postType":"post"}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-date /-->
<!-- wp:post-excerpt {"moreText":"Read article"} /-->
<!-- /wp:post-template -->
<!-- wp:query-pagination /-->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->
This declarative format eliminates PHP syntax errors in presentation templates. In parts/header.html, you can define your brand logo and navigation block:
<!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<div class="wp-block-group">
<!-- wp:site-title /-->
<!-- wp:navigation /-->
</div>
<!-- /wp:group -->
Because these components are native block template parts, editors can modify navigation items or site branding visually inside the WordPress admin without touching theme code.
Registering Custom Block Patterns for Reusable Sections
Block patterns allow you to assemble pre-designed layouts—such as pricing tables, FAQ accordions, and hero banners—that users can insert with a single click.
Patterns can be registered effortlessly using a dedicated PHP file placed in your theme's patterns/ directory:
<?php
/**
* Title: Feature Callout
* Slug: custom-theme/feature-callout
* Categories: featured, call-to-action
*/
?>
<!-- wp:group {"style":{"spacing":{"padding":{"top":"3rem","bottom":"3rem"}}},"backgroundColor":"contrast"} -->
<div class="wp-block-group has-contrast-background-color">
<!-- wp:heading {"textAlign":"center","textColor":"base"} -->
<h2 class="wp-block-heading has-text-align-center has-base-color">Build Faster with Clean Block Primitives</h2>
<!-- /wp:heading -->
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons">
<!-- wp:button {"className":"is-style-fill"} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="/pricing">Get Started</a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
</div>
<!-- /wp:group -->
WordPress automatically detects files in the patterns/ folder and makes them accessible in the Gutenberg block inserter, turning your theme into an intuitive design kit.
Performance Tuning and Production Deployment
Block themes are inherently faster than classic themes because WordPress only injects the CSS styles required by the blocks actually present on the rendered page. However, keeping load times under 800 milliseconds requires deliberate optimization:
- Self-Host Web Fonts: Use the WordPress Font Library in
theme.jsonto load fonts locally instead of triggering third-party DNS lookups to external font providers. - Disable Unnecessary Core Block Assets: If your custom build does not use heavy core widgets (like calendar or tag cloud blocks), dequeue them via
functions.php. - Audit Template Complexity: Avoid deeply nested groups and wrapper blocks that bloat the final DOM tree unnecessarily.
If you are developing complex content hubs or marketing sites, pairing a custom block theme with dedicated blog templates or modular starter kits ensures that your publication ranks high on Google while delivering instant page transitions.
Build Modern WordPress Solutions Faster
Explore curated themes, starters, and boilerplates designed for professional developers:
Featured WordPress templates & starter kits
Skip weeks of boilerplate setup with complete source code, authentication, and modern UI.
Related guides & tutorials
What Is a WordPress Block Theme and How Does It Work
Learn what a WordPress block theme is and how it works under the hood. Discover HTML templates, theme.json configuration, and Full Site Editing mechanics.
WordPress Block Theme vs Classic Theme: Which Should You Choose
WordPress block themes vs classic themes: compare full site editing, performance, development workflows, and theme.json to pick the right architecture.
Best WordPress Block Themes for Full Site Editing
Explore the best WordPress block themes for Full Site Editing (FSE). Compare performance, theme.json customization, and modern Gutenberg design workflows.
Best Landing Page Templates for WordPress
Discover the best landing page templates for WordPress. Compare block themes, page builder alternatives, Full Site Editing, and high-converting layouts.
Best Astro Themes for Blogs, Docs and Marketing Sites
Discover the best Astro themes for blogs, documentation, and marketing websites. Compare performance, content collections, and zero-JS delivery features.
Astro SaaS Boilerplate: Is Astro a Good Fit for SaaS
Analyze if an Astro SaaS boilerplate fits your product. Compare island architecture, SSR features, auth flows, and full-stack performance trade-offs.
Ready to ship faster?
Browse production-ready web framework templates and starter kits.
Browse templates