I Built My WordPress Theme to Be Read by Machines

Most WordPress themes are designed for humans — the people who click around the Site Editor, tweak colors in the Customizer, and occasionally break things they can’t explain. Mine was designed for something else: AI agents.

Not because humans don’t matter. But because designing for machine readability turns out to produce a cleaner, faster, more honest architecture than designing for human convenience alone.

Here’s what I learned building it.


The problem with “flexibility”

The dominant WordPress themes — the ones recommended in every “best of” list — are multipurpose frameworks. Astra. GeneratePress. Kadence. They’re genuinely good pieces of software. But they make a specific trade-off: they prioritize flexibility over structure.

You can do almost anything with them. And that’s exactly the problem.

When a theme can produce any layout, any color combination, any nesting depth, the resulting HTML becomes unpredictable. Fine for humans browsing a page. Genuinely difficult for an AI agent trying to parse, generate, or manipulate content programmatically.

Autonomous agents don’t need drag-and-drop. They need clean schemas, predictable markup, and structured data they can reason about.


What Full Site Editing actually makes possible

WordPress 6.6 introduced theme.json version 3. It’s easy to miss the significance of this if you’re not building themes — but what it does is move the entire design system into a single, machine-readable declarative file.

Colors, typography, spacing, layout boundaries: all defined once, all expressed as semantic tokens, all accessible to anything that can read JSON.

This is what made the architecture I was aiming for actually feasible. Instead of scattered CSS variables across multiple stylesheets, you have one file that acts as the single source of truth. When an AI agent needs to understand the design constraints — or generate content within them — it reads theme.json. Everything it needs is there.

No proprietary shortcodes. No PHP parsing required. Just block markup and a JSON configuration.


The design decisions that mattered most

A few choices shaped everything else.

Locking the color palette. I defined six semantic color tokens — Base, Surface, Contrast, Muted, Border, Primary — and then set "defaultPalette": false and "custom": false in theme.json. This means neither a human editor nor an AI agent can introduce an arbitrary color. If something tries to apply #ff0000 to a heading, the system ignores it and falls back to the defined tokens.

This isn’t about being restrictive. It’s about being trustworthy. If you can’t introduce arbitrary values, you can’t accidentally break accessibility contrast ratios.

Fluid typography without media queries. The entire type scale uses CSS clamp() — body text scales from 16px at 320px viewport to 18px at 1200px, with every heading level following a Major Third ratio. No breakpoints involved. The math handles the responsiveness.

What this gives you practically: a type system that works correctly across every device without a line of JavaScript, and one that an AI generating content can rely on producing predictably legible output.

Keeping functions.php nearly empty. In a traditional WordPress theme, functions.php becomes a dumping ground. In this architecture, it does exactly three things: enqueues local fonts, removes legacy emoji detection scripts, and strips the XML-RPC endpoints. That’s it. No display logic. No HTML output. No templating.

Everything else lives where it belongs.


The part about performance that surprised me

I expected the architecture to be clean. I didn’t fully anticipate how much the performance would improve as a direct side effect of the structural decisions.

WordPress 6.9 raised the inline style limit from 20KB to 40KB and introduced automatic dequeuing of block-specific styles when those blocks aren’t present in the DOM. Because this theme uses only native blocks and generates all CSS through theme.json, the browser only ever receives the styles it actually needs. No global stylesheet loaded unconditionally on every page.

The result: LCP under 2.5 seconds, CLS below 0.1, TTFB under 200ms — not because I spent time optimizing, but because the architecture doesn’t load what it doesn’t use.

The cleaner structure produced the faster site. That connection felt worth documenting.


What AI agent integration looks like in practice

The MCP (Model Context Protocol) Adapter — now part of the WordPress AI ecosystem — serves as a translation layer between the WordPress database and external language models. Because this theme uses pure block HTML rather than PHP templating, an AI agent can read the template files with basic text analysis.

The practical implication: an agent can generate a new page layout by fetching registered block patterns from the REST API and assembling them. It doesn’t hallucinate HTML because the patterns constrain what it can output. It doesn’t introduce off-brand colors because theme.json rejects them.

The design system becomes a set of guardrails the agent is forced to operate within. The output stays coherent.


What I’m still figuring out

The blueprint I published describes the architecture at a point-in-time. I’m still working through questions about how AI agents handle revision history, how to expose theme tokens to external LLMs in a way that’s useful without being overwhelming, and whether the patterns-as-API-endpoints approach scales gracefully to more complex content types.

These aren’t complaints. They’re the parts of the problem I find genuinely interesting.


The full research

If you want the complete blueprint — exact theme.json configuration, file structure, implementation phases, and performance benchmarks — the research paper is published at goutamprusty.com/research.

The implementation is live. The site you’re reading this on runs the architecture described in that document.

Leave a Comment