How I build Gutenberg blocks with AI agents
Agents scaffold the block, write the boilerplate and the first tests. I write the editor experience, the markup decisions and the review. Here is the workflow, step by step.
Zakaria Binsaifullah · · 4 min read
I have been building Gutenberg blocks since the block editor shipped, and leading development on block plugins for the last few years. Today most of my blocks start with AI agents. Not because the agents are better at WordPress than I am — they aren't — but because a block has a lot of predictable code around a small amount of code that really matters.
This post is the workflow I actually use: what I hand to the agents, what I keep for myself, and the checklist every block goes through before it ships.
The split: boring code vs. decisions
A typical custom block touches the same files every time:
block.json— name, attributes, supports, scripts and stylesedit.tsx— the editor UI: inspector controls, toolbar, placeholderssave.tsx(or arender.phpfor dynamic blocks)styles for the editor and the front end
a PHP file to register it, and usually a test or two
Most of that is structure, not judgement. Agents are fast and reliable at structure. Where they are weak is exactly where blocks succeed or fail: how the block feels to edit, what markup it leaves behind, and whether it still works the day you change it.
So the rule is simple: agents write the scaffolding and the first draft, I write the decisions, and nothing ships until I have read every line.
Step 1: a brief the agents can't misread
Every block starts as a short written brief. Not a chat message — a file. It answers:
Who edits this block, and what do they change most? A pricing card gets its plan name, price and features edited constantly; its layout almost never.
Static or dynamic? If the output depends on data that changes (posts, products, prices), it renders on the server. Otherwise it is saved markup.
What does the front end output look like? I write the target HTML by hand. This is the single most useful thing in the brief — it stops agents from inventing wrapper divs.
What must be accessible? Headings, focus order, labels, colour contrast in both themes.
A planner agent turns that brief into tasks. I read the task list before anything gets built. This is where most mistakes are cheapest to fix.
Step 2: the agents scaffold
The builder agent creates the block from the plan. For a pricing card the attributes end up something like this:
{
"apiVersion": 3,
"name": "dz/pricing-card",
"title": "Pricing card",
"category": "design",
"attributes": {
"plan": { "type": "string", "source": "html", "selector": "h3" },
"price": { "type": "string", "default": "$49" },
"features": { "type": "array", "default": [] },
"highlighted": { "type": "boolean", "default": false }
},
"supports": { "color": { "background": true, "text": true }, "spacing": { "padding": true } }
}
And a first pass at the editor component:
export default function Edit({ attributes, setAttributes }) {
const { plan, price } = attributes;
const blockProps = useBlockProps({ className: 'pricing-card' });
return (
<div {...blockProps}>
<RichText tagName="h3" value={plan} onChange={(plan) => setAttributes({ plan })} placeholder="Plan name" />
<RichText tagName="p" className="price" value={price} onChange={(price) => setAttributes({ price })} />
</div>
);
}
That gets me from an empty folder to a block that registers, renders and saves in minutes. It is not finished — it is a starting point I don't have to type.
Step 3: the parts I write by hand
This is the work clients are actually paying for.
The editing experience. Agents tend to put every option in the sidebar. I move the things people change constantly into the canvas (inline RichText, toolbar buttons) and leave rare settings in the inspector. A block should be editable without hunting.
The saved markup. I compare the output against the HTML I wrote in the brief, element by element. Extra wrappers, inline styles and missing semantic tags get removed now, because changing saved markup later means writing deprecations.
Attributes that will survive. Once a block is in use, renaming an attribute or changing its source breaks existing content. I decide the attribute shape deliberately and add a deprecated entry the moment I change anything that has shipped.
Theme and editor parity. I check the block in the editor and on the front end with real theme styles, in light and dark, on mobile. Block supports (colour, spacing, typography) should do the work instead of custom controls wherever possible.
Step 4: review — every change, every time
The reviewer agent runs linting, builds and the tests, and flags obvious problems. Then I review the diff myself with a short checklist:
Does the saved markup match the brief? No surprise wrappers or inline styles.
Can a keyboard user reach and edit everything? Are headings in order?
Does it validate after a reload? (Block validation errors are the classic Gutenberg bug.)
Are strings translatable and escaped on output?
Does it still work with the theme's colours, fonts and spacing?
Is there anything here I wouldn't be happy to maintain in a year?
Anything that fails goes back as a specific change request — "remove the wrapper div, use the h3 from the brief" — not "make it better". Agents respond well to precise feedback and badly to vague feedback, which is true of most people too.
What this changes for clients
The honest summary: the scaffolding that used to take a morning now takes minutes, so more of the budget goes into the editing experience, accessibility and the details that make a block pleasant to use. The quality bar doesn't move, because the review step doesn't move.
If you need a custom block — or a whole block plugin — and want it built this way, book a 20-minute call or send me a short brief.
Related
- Plan, build, review: how I direct several coding agents at once
One agent plans, another writes, another reviews — and a human reads every change. How I split the work between coding agents, keep them on track, and decide what never gets delegated.
- How this site works: Astro on Cloudflare Workers, edited from D1
A portfolio that is fast, cheap to run and still has a real CMS. The stack behind devzakaria.com — Astro, Cloudflare Workers, D1, KV, R2 — plus the caching bugs I found along the way.