Claude Code for WordPress Development: How to Actually Use It
How to use Claude Code for WordPress development: Gutenberg scaffolding, plugin architecture, FSE patterns, and what to review before you ship.
It's 2022. I'm three hours into setting up a testimonial block in WordPress (the third one that quarter), and I stop to look up whether RichText.Content goes in the save function or the render callback. I already know the answer; I've done this exact thing several times over the years. But the context-switching still costs some minutes, and by the time I'm back, I have forgotten what I was actually trying to solve.
That's when Claude started becoming useful for my WordPress work.
Not as a replacement for understanding the codebase. If you don't know what wp_enqueue_scripts does, Claude generating it for you doesn't help you debug it later, when the client complains about a bug. But as a way to stay on top of the problem while it handles the mechanics: block scaffolding, hook registration, the register_post_type argument array I rewrite from scratch every project because I never remember if has_archive goes before or after rewrite, even after creating some macros on VSCode. Claude handles the machinery while I focus on the architecture. He’s my intern, my junior developer, and my rubber duck, all at the same time.
So, here's how I actually use it, with enough detail to be immediately useful.
Before You Write a Single Prompt
The productivity gap between "Claude is useful" and "Claude is annoying" lives almost entirely in the initial context. Paste a vague request and get generic code. Give Claude your project's real constraints and get something you can drop directly into wp-content/plugins/ with a code review and a test run.
I keep a project context template saved as markdown. It takes two minutes to fill in and eliminates most of the revision loops:
# WordPress Plugin — Claude Code Context
## Project identity
- Plugin name: [Plugin Name]
- Text domain: [text-domain]
- WordPress minimum: 6.6
- PHP minimum: 8.2
- Build tool: @wordpress/scripts
## Before you generate anything
Read the main plugin file and one existing class before writing any new code.
If blocks exist, read one complete block (block.json + edit.js + render.php) before creating another.
If patterns exist, read patterns/ before creating a new pattern.
Match naming, class structure, and file organization to what already exists.
## Architecture
- Hooks register through a Loader class (includes/class-loader.php). Add new hooks there, not inline.
- One class per file. Filename: class-[classname].php in kebab-case.
- Blocks: src/blocks/[block-name]/ — each block has its own directory.
- Custom post types: includes/class-post-types.php
- REST endpoints: includes/class-rest-api.php
- Admin: admin/class-admin.php
- Frontend: public/class-public.php
## JavaScript
- No jQuery. Use native wp.* APIs or vanilla JS.
- REST API for async operations. No new wp_ajax_ hooks.
- ES modules only. No CommonJS require().
- For interactive blocks: use the Interactivity API (wp-interactivity), not custom event listeners.
## Security — non-negotiable
- Sanitize all input: `sanitize_text_field()`, `absint()`, `wp_kses_post()` — match the function to the data type.
- Escape all output: `esc_html()`, `esc_url()`, `esc_attr()` — never echo raw.
- Verify nonces on all form submissions and REST write handlers.
- Check capabilities before any data write. Use the most specific capability available, not `edit_posts` as a catch-all.
- `$wpdb->prepare()` on every direct query, no exceptions.
## What not to do
- No deprecated functions. If unsure, check the WP changelog against the version minimum.
- No hardcoded plugin version in `wp_enqueue_*`. Use the plugin constant.
- No `extract()`. No short PHP tags.
- Don't set `publicly_queryable => true` on a CPT unless it needs a public archive.
- No WP_Query that fetches full post objects when only IDs or meta are needed.
- No hooks inside class constructors. They go through the Loader.
- No `update_option()` calls without checking current value first on large data.
## Standards
- PHPCS with WordPress ruleset throughout.
- All user-facing strings wrapped with the plugin text domain.
- DocBlocks on all classes and public methods.
## Before you call a task done
Scan the files you created or modified for:
1. Deprecated functions for this WP version minimum
2. Unescaped output
3. Missing capability checks on write operations
4. Nonces on every form and REST write endpoint
5. Any `publicly_queryable` set incorrectly
6. Strings missing internationalization
7. Hooks registered outside the Loader
Save it as the initial CLAUDE.md for the project, or in your Claude Web project prompt, and make the real prompt later. This does something specific: it forces Claude to generate code that matches your actual project instead of generic WordPress examples from 2019. It’ll follow the standard for that PHP version. It’ll research what that WordPress version can do that it can't. If you're still supporting WordPress 5.8, say so. If you need it to be compatible with PHP 7.4, make it clear - or your plugin will fail in production.
The context window is large enough to hold your entire plugin structure plus examples. Use it.
Building Gutenberg Blocks Step by Step
Starting With the Scaffold
A new Gutenberg block requires four files at minimum: block.json, an edit.js component, a PHP render callback, and a stylesheet. The actual functionality is what takes time. The scaffold shouldn't be.
With Claude Code running inside your project directory, the starting point is different from the web interface. You don't describe your file structure; Claude Code reads it. It sees what's already in src/blocks/, how your existing block.json files are structured, and what naming convention you're using for classes. The context is the actual codebase.
The prompt becomes:
Look at the existing blocks in src/blocks/ to understand my conventions.
Then create a testimonial block:
- Quote text (RichText, strip_tags on save)
- Author name (PlainText)
- Author photo (MediaUpload with image preview in editor)
- Star rating (number attribute, 1–5, stored as integer)
- Optional background color from theme color palette
Create the four files in the right directory.
Claude Code creates block.json, edit.js, render.php, and style.scss directly. No copy-paste. The block.json will have correct attribute sources, the render callback will have esc_html() and absint() where they belong, and the class names will match your existing pattern — because Claude Code checked before generating.
You still review before committing. More on that later.
This compounds when you're building a design system with twelve block types. Every scaffold follows your actual conventions, not a generic WordPress example.
Adding Block Variations
Block variations are where file access pays off most. Claude Code reads your existing card block before generating horizontal and stacked variants, so the attribute names, class names, and default values match what you already have.
Save variations in src/blocks/card/variations.js. Claude Code creates the file and imports it into edit.js if you ask.
The question it still can't answer: whether a variation is the right pattern at all, or whether you need a separate block. That depends on the editor experience you're designing for.
InnerBlocks and Constraint Logic
InnerBlocks patterns get complicated quickly with allowedBlocks, template locks, and orientation settings. Ask for the complete implementation, including the template array and lock settings. Specify how many blocks the user can add, whether the template is locked, and which block types are permitted inside.
Ask Claude Code to check your existing InnerBlocks implementations first. Consistency across your block library matters more than any individual block being technically correct in isolation.
Test the editor experience manually afterward. What looks right in code sometimes creates unexpected UX in the block editor.
Plugin Architecture Without the Ceremony
The Loader Pattern
Claude Code reads your main plugin file before generating anything. If you've already got a structure, it extends it instead of producing a fresh scaffold that conflicts with what's there. Starting from scratch, the prompt is:
Generate a WordPress plugin scaffold with a loader pattern:
- Plugin name: Your Plugin, text domain: your-plugin
- Loader class stores arrays of actions and filters, executes them on run()
- Admin class enqueues admin-only scripts on admin_enqueue_scripts
- Public class enqueues frontend scripts on wp_enqueue_scripts
- Main plugin file instantiates and runs everything on plugins_loaded
Create all files in the correct directories.
Claude Code creates includes/class-loader.php, admin/class-admin.php, public/class-public.php, and the main plugin file. You add your actual functionality into the existing class structure. This is where the scaffold pays off — you're adding methods to organized classes, not dumping everything into one monolithic file that becomes unmaintainable after month three.
Custom Post Types
The register_post_type argument array has about thirty possible keys. You use maybe ten of them regularly. Claude Code generates the complete call from a plain description and creates or updates the right file:
Register custom post type 'project':
- Hierarchical (like pages)
- Archive at /projects/
- Supports: title, editor, thumbnail, custom-fields
- Custom capabilities: edit_projects, publish_projects
- Map meta cap: true
- Exclude from default search results
If you've already got a post types class, Claude Code adds the new CPT to it. One review pass to confirm the rewrite slug, capability names, and that publicly_queryable is set correctly. Ask Claude Code to check your existing capability definitions in the same session before you close it.
Custom Database Queries
When you need a WP_Query beyond a standard post loop, Claude Code generates the argument array and can scan your existing queries for the N+1 pattern before it compounds. Include only the fields you actually need — fields => 'ids' when you just need IDs, no_found_rows => true when you don't need pagination.
A query that fetches full post objects when you only need titles is harmless on a small site and a real problem on a large one. For more on WordPress speed optimization, there's a breakdown of how query structure affects page performance at scale.
FSE Patterns at Scale
Block patterns are one of the most repetitive tasks in FSE theme development. The markup for a hero section with a background image, heading, and CTA is not hard — it's just dense. With Claude Code in your theme directory, it reads your existing patterns before generating new ones. No naming conflicts. Class names that match what you already have.
Look at the patterns in patterns/ to understand the naming conventions.
Then generate a hero-with-cta pattern:
- Pattern slug: hero-with-cta
- Category: theme/heroes
- Full-width Cover block with a 50% dark overlay
- Inside: constrained Group with H1, paragraph, and Button block
- Core blocks only
- PHP docblock for automatic registration in WordPress 6.4+
Create the file in patterns/.
Claude Code creates the file. Test it in the editor, and adjust spacing to your design tokens.
On Getting It Wrong
This section is longer than the others because it's the one that matters when something breaks in production.
Claude Code generates plausible code. Plausible is not the same as correct, and correct is not the same as safe for your specific context. The failure modes I've personally hit: a REST endpoint that verified nonces but didn't check user capabilities before writing data; a WP_Query that fetched complete post objects when I only needed IDs, harmless until the site had 80,000 posts; a register_post_type call that left publicly_queryable set to true for a CPT meant to stay internal. None of these were caught automatically. All were caught by reading the code before shipping.
Claude Code catches more than the web interface does, because it can search your actual codebase. After generating, ask it to review its own output:
Review the files you just created for:
- Deprecated WordPress functions
- Missing capability checks
- Unescaped output
- Any function names I should verify against the WP docs for my version
It may or may not find problems. But it’s common to see some problems escape through the review.
The security gap that remains is specific: Claude Code knows the patterns: sanitize on input, escape on output, verify nonces on form submissions. What it doesn't know is your permission model. If your plugin has multiple user roles interacting with the same data, Claude Code will often write capability checks that are technically correct in isolation and wrong for your setup. It might check current_user_can('edit_posts') where your plugin requires a custom capability defined in another file. That's not a hallucination. It’s a context you haven't given it. Fix it by asking Claude Code to read your existing capability structure before writing the endpoint.
Database migrations are still the one category where I treat Claude Code's output as a first draft. The migration code is usually fine. What's missing is knowledge of your live data: the posts imported six years ago with unusual meta values, the legacy rows that don't conform to the schema you assumed was universal. Claude Code can't know those. Run migrations against a staging database with a production snapshot first. That holds whether Claude Code wrote the code or you did.
The deprecated functions issue is real but catchable. Claude Code's training data includes a lot of older WordPress code, and it occasionally reaches for functions that still exist but were deprecated in 5.5 or 6.0. Ask it to scan for these after generating. It usually finds them. The scan still takes thirty seconds. Don't skip it.
Read every file before it goes into version control. The fact that Claude Code created the file directly doesn't make the review optional.
Finally, after fixing what you can and when you feel the codebase has evolved enough already, ask Claude Code to review the codebase and update CLAUDE.md with the new patterns and issue checks you have created, to ensure that it won’t repeat past behaviours.
Claude Code is fast and has context on your actual codebase. You are still responsible for what ships. Believe me: both things are true.
Using Claude Code for WordPress Development isn’t a speed gain if you count individual tasks. It's the accumulation: the fifteen minutes you didn't spend in documentation, the boilerplate you didn't write from scratch for the eighth time, the conventions that stayed consistent across twelve blocks without you enforcing them manually, the review pass that caught the permissions issue before it hit production.
Claude Code handles the basic and boring work. HOW that will be built is still something that you decide.
If you're working on complex WordPress plugin architecture and want a technical review of the structure, security model, or performance characteristics before it goes live, that's the kind of engagement I take on. Here's how I work.