Technical
Building a WordPress Plugin with Claude Code
Clients ask for WordPress features that no plugin solves exactly. Custom newsletter signup with double opt-in, custom post type for case studies, shortcode that pulls from an external API. I used to quote a week. Now I deliver in an afternoon using Claude Code as my plugin scaffolder.
Why WordPress Still Matters
WordPress powers the site the client will edit after I leave. I can write a Next.js masterpiece, but if the client cannot add a blog post without calling me, I failed. WordPress gives them the admin UI they already know. My job is to extend it cleanly.
The Plugin Skeleton
Every plugin needs a header, an activation hook, and a safety check. Claude Code generates all three in one prompt:
Create a WordPress plugin called 'PeakLight Subscribers' in
wp-content/plugins/peaklight-subscribers/. Add the main PHP
file with the plugin header, a shortcode [peaklight_signup],
and a REST endpoint /wp-json/peaklight/v1/subscribe.The agent writes the plugin header, the shortcode callback, and the register_rest_route call with proper argument validation.
add_action('rest_api_init', function () {
register_rest_route('peaklight/v1', '/subscribe', [
'methods' => 'POST',
'callback' => 'peaklight_handle_subscribe',
'permission_callback' => '__return_true',
]);
});What I Still Decide
I decide the data shape, the validation rules, and the error responses. The agent does not know that my client wants emails normalized to lowercase before storage. I tell it that. The agent writes the normalization. That is the division of labor.
Testing on a Local Stack
I run WordPress locally with LocalWP. Plugin changes show up instantly. When the agent finishes the plugin, I activate it in the WP admin, hit the REST endpoint with curl, and verify the row lands in the database.
Why This Is Agentic Development
I am not hand-writing PHP. I am not copy-pasting from WordPress tutorials. I am directing an agent that reads WordPress conventions, my data requirements, and produces a plugin that fits both. The client gets a tool they can manage from their familiar admin screen. I get my afternoon back.
Activation and Cleanup Hooks
Every plugin I ship includes an activation hook to create database tables and a deactivation hook to clean up options. Claude Code writes those in one prompt because they are conventional WordPress patterns:
register_activation_hook(__FILE__, 'peaklight_activate');
register_deactivation_hook(__FILE__, 'peaklight_deactivate');Predictable activation behavior is what separates a real plugin from a script in disguise.
Versioning and Updates
I version every plugin in the main file header and use get_option to compare the installed version against the current code. When they differ, I run a migration function. That lets me evolve the plugin for the client without manual SQL on their server.
See the WordPress Plugin Handbook for the conventions Claude Code follows when scaffolding plugins.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read