Where Creativity Meets Technology

Let’s collaborate to create unforgettable digital experiences that drive results.

WordPress Plugin Development: A Clear, Hands-On Tutorial for Building Your First Plugin

WordPress plugin development is the process of writing PHP (and often JavaScript) code that extends WordPress without touching core files. You build a plugin by creating a folder in /wp-content/plugins/, adding a main PHP file with a plugin header, and connecting your code to WordPress through hooks. This tutorial walks you through every step with working code, current tooling, and the security rules the official Plugin Directory enforces in 2026.

That short answer gets you oriented. The rest of this guide gets you shipping.

Here is why this matters right now. WordPress powers roughly 42% of all websites and holds about 60% of the CMS market as of mid 2026. The official directory lists more than 65,000 free plugins, and the WordPress Plugin Team reviewed 12,713 new submissions in 2025 alone, a 40.6% jump over the prior year. The ecosystem is crowded, active, and still hungry for well-built tools.

There is also a fresh reason to learn this skill today: WordPress 7.0 “Armstrong,” released May 20, 2026, lets you register editor blocks using only PHP. The JavaScript build pipeline that scared off thousands of PHP developers is no longer mandatory for simple blocks. The barrier to entry just dropped hard.

What a WordPress Plugin Actually Is (and Why You Never Edit Core)

A plugin is a self-contained package of code that WordPress loads at runtime. Core files get overwritten on every update, so any change you make there vanishes. Plugins survive updates because they live in their own directory and talk to WordPress through a stable API.

One plugin can be a single 20-line PHP file. Another can be WooCommerce, which runs about a fifth of all WordPress sites. Same architecture, wildly different scale. That range is the point: the plugin system is how WordPress stays lean while supporting everything from contact forms to full storefronts.

The Four Building Blocks Every Plugin Developer Must Know

Before writing your first line, learn the vocabulary WordPress speaks.

1. Hooks: Actions and Filters

Hooks are the connection points between your code and WordPress. There are two kinds:

  • Action hooks run your function at a specific moment. When a post publishes, when a user logs in, when the admin menu builds. You add behavior.
  • Filter hooks intercept data, let you modify it, and pass it back. Change a post title before display, rewrite an email subject, adjust a query. You transform data.

The syntax is nearly identical:

// Action: run code when a post is published

add_action( ‘publish_post’, ‘xceed_notify_team’ );

// Filter: modify content before it renders

add_filter( ‘the_content’, ‘xceed_append_disclaimer’ );

WordPress core exposes over 2,000 hooks. Mastering even 30 of the common ones covers most real-world plugin work. Both functions accept a priority argument (default 10) that controls execution order, and remove_action() lets your plugin detach behavior another plugin or theme added. That composability is what makes the hook system so durable.

2. Blocks

Since the block editor arrived in WordPress 5.0, blocks are the primary way users insert plugin content into pages. Historically that meant learning React, Node.js, and a build toolchain. As of WordPress 7.0, simple server-rendered blocks need none of that (more on this below).

3. Shortcodes

Shortcodes like [your_plugin_output] are the classic insertion method. They still work everywhere, including page builders and classic-editor sites, so supporting both a block and a shortcode remains a smart compatibility play in 2026.

4. The REST API and Settings API

Modern plugins expose data through REST endpoints and store configuration through the Settings API. If your plugin needs an options page or needs to talk to JavaScript, these two APIs are your foundation.

Widgets, for the record, are effectively legacy. WordPress replaced the widget system with blocks back in version 5.8, so skip them for new projects unless a client specifically runs the Classic Widgets plugin.

Step-by-Step: Build a Working Plugin in 7 Steps

This walkthrough builds a real plugin called Reading Time Badge that displays estimated reading time above post content. Simple enough to finish today, real enough to teach the full workflow.

Step 1: Define the Requirement in One Sentence

“Show an estimated reading time above every blog post, with a settings page to change the words-per-minute rate.” If you cannot state the job in one sentence, the scope is not ready. Vague scope is the top reason first plugins stall.

Step 2: Set Up a Local Environment in Minutes

Do not develop on a live site. Two current options:

  • wp-env: the official tool. Run npx @wp-env/cli start (or wp-env start) inside your plugin folder and you get a full WordPress site at localhost:8888. Since early 2026 it can run on the WordPress Playground runtime, so Docker is no longer required.
  • LocalWP or WordPress Studio: GUI apps if you prefer point-and-click site management.

Step 3: Create the Structure and Plugin Header

Make the folder and main file:

/wp-content/plugins/reading-time-badge/

    reading-time-badge.php

    /includes/

    /assets/

The header comment is what makes WordPress recognize your file as a plugin:

<?php

/**

 * Plugin Name: Reading Time Badge

 * Description: Displays estimated reading time above posts.

 * Version: 1.0.0

 * Requires at least: 6.5

 * Requires PHP: 7.4

 * Author: XCEEDBD

 * License: GPLv2 or later

 * Text Domain: reading-time-badge

 */

if ( ! defined( ‘ABSPATH’ ) ) {

    exit; // Block direct file access.

}

That ABSPATH check is not optional style. The official Plugin Check tool now flags files that skip it.

Step 4: Add the Core Functionality with a Filter

function rtb_add_badge( $content ) {

    if ( ! is_singular( ‘post’ ) || ! in_the_loop() ) {

        return $content;

    }

    $wpm     = (int) get_option( ‘rtb_wpm’, 200 );

    $words   = str_word_count( wp_strip_all_tags( $content ) );

    $minutes = max( 1, ceil( $words / $wpm ) );

    $badge   = ‘<p class=”rtb-badge”>’ . sprintf(

        esc_html__( ‘Reading time: %d min’, ‘reading-time-badge’ ),

        $minutes

    ) . ‘</p>’;

    return $badge . $content;

}

add_filter( ‘the_content’, ‘rtb_add_badge’ );

Notice three habits baked in: the conditional guard so the badge only appears on single posts, the rtb_ prefix on every function to prevent naming collisions, and esc_html__() for translatable, escaped output.

Step 5: Add a Settings Field the WordPress Way

function rtb_register_settings() {

    register_setting( ‘reading’, ‘rtb_wpm’, array(

        ‘type’              => ‘integer’,

        ‘sanitize_callback’ => ‘absint’,

        ‘default’           => 200,

    ) );

    add_settings_field(

        ‘rtb_wpm’,

        __( ‘Words per minute’, ‘reading-time-badge’ ),

        ‘rtb_wpm_field_html’,

        ‘reading’,

        ‘default’

    );

}

add_action( ‘admin_init’, ‘rtb_register_settings’ );

The sanitize_callback line is doing real security work: every saved value passes through absint(), so nothing but a positive integer ever reaches the database.

Step 6: Handle Activation and Cleanup

register_activation_hook( __FILE__, function () {

    add_option( ‘rtb_wpm’, 200 );

} );

register_uninstall_hook( __FILE__, ‘rtb_uninstall’ );

function rtb_uninstall() {

    delete_option( ‘rtb_wpm’ );

}

Plugins that leave orphaned options and tables behind are a leading cause of bloated databases. Clean up after yourself and reviewers, hosts, and users will all notice.

Step 7: Test, Package, Ship

Zip the folder, upload it through Plugins > Add New on a staging site, and confirm behavior. For distribution beyond your own sites, run the official Plugin Check plugin first (details below), then submit to WordPress.org or deliver directly to the client.

The 2026 Shortcut: PHP-Only Blocks in WordPress 7.0

This deserves its own section because it changes who can build blocks.

Before 7.0, shipping even a trivial block meant Node.js, npm, React, and a webpack or wp-scripts build step. WordPress 7.0 added PHP-only block registration: set ‘autoRegister’ => true in the block’s supports array, and WordPress generates the client-side registration and inspector controls for you.

register_block_type( ‘rtb/badge’, array(

    ‘render_callback’ => ‘rtb_render_block’,

    ‘supports’        => array( ‘autoRegister’ => true ),

) );

For dynamic, server-rendered blocks (stat counters, latest-posts lists, CTAs, badges like ours), that is the whole story. No build folder, no node_modules. You still want the JavaScript toolchain (@wordpress/create-block scaffolding plus the new esbuild-based build pipeline) for rich interactive blocks, but it is now a choice, not a toll gate.

WordPress 7.0 also shipped a native AI Client and Abilities API, giving plugins one standard interface to OpenAI, Anthropic, and Google models through the new Connectors screen. If you have been eyeing an AI-powered plugin idea, the plumbing now ships in core.

Security: The Part That Decides Whether Your Plugin Survives

The numbers here are blunt. Patchstack logged 11,334 new vulnerabilities across the WordPress ecosystem in 2025, up 42% year over year, and roughly 91% of them lived in plugins. WordPress core accounted for just 6. When a WordPress site gets hacked, the door was almost always a plugin.

Four rules prevent the vast majority of those flaws:

  1. Sanitize on input. Every value from a form, URL, or API passes through sanitize_text_field(), absint(), sanitize_email(), or a similar function before you store it.
  2. Escape on output. Use esc_html(), esc_attr(), and esc_url() at the exact moment of printing. Escaping late catches data that snuck in dirty.
  3. Verify nonces on every form and AJAX action. wp_nonce_field() plus check_admin_referer() shuts down cross-site request forgery.
  4. Check capabilities before privileged actions. current_user_can( ‘manage_options’ ) ensures a subscriber cannot trigger admin behavior.

Cross-site scripting remains the single most common plugin vulnerability class in the Patchstack database, and nearly every instance traces back to skipped escaping. These four habits cost minutes and save reputations.

Modern Plugin Development Tools (Skip the Dead Editors)

Plenty of older tutorials still recommend Brackets and Atom. Both editors are discontinued: Adobe ended Brackets support in 2021 and GitHub sunset Atom in December 2022. Here is the stack working developers actually use in 2026:

ToolWhat It DoesCost
VS Code + PHP IntelephenseEditing, autocomplete, WordPress-aware IntelliSenseFree
wp-envDisposable local WordPress environments (Docker or Playground runtime)Free
WP-CLICommand-line control: scaffold, activate, test, manageFree
Query MonitorIn-browser debugging of hooks, queries, HTTP callsFree
Plugin Check (PCP)The official pre-submission scanner used by the review teamFree
PHPUnit + wp-scriptsAutomated PHP and JavaScript testingFree
WordPress PlaygroundBrowser-based WordPress for instant demos; supports about 99% of pluginsFree

Notice the total cost of that column: zero. The entire professional WordPress toolchain is free, which is part of why an estimated $596.7 billion economy has grown around the platform.

One workflow tip that pays off immediately: WordPress Playground lets you share a live demo of your plugin with a single URL. Append your plugin slug as a query parameter and anyone can test it in their browser with no installation. For client approvals and support triage, that is a genuine time-saver.

Testing and Releasing Your Plugin

Before any release, run this sequence:

  1. Plugin Check. Install the PCP plugin, go to Tools > Plugin Check, and fix every error. The 2026 releases added checks for direct file access, insecure nonce use, and mismatched “Tested up to” headers, the same checks WordPress.org reviewers run.
  2. Test against supported versions. WordPress 7.0 requires PHP 7.4 minimum and recommends 8.3. Test at both ends of your declared range, because about a fifth of live WordPress sites still run PHP 7.4.
  3. Enable WP_DEBUG and confirm zero notices or warnings in normal operation.
  4. Write a real readme.txt with an accurate changelog. It powers your directory listing and your search visibility inside WordPress admin.

For WordPress.org submission, your plugin must carry a GPLv2-or-later compatible license. Review currently takes days to a few weeks depending on queue depth, and clean Plugin Check results dramatically reduce back-and-forth with the review team.

Build It Yourself or Hire It Out? A Quick Decision Framework

Honest guidance, since we sit on both sides of this question:

  • Build it yourself when the plugin is internal, the scope fits in a sentence, and a delay costs you nothing. The tutorial above covers this case fully.
  • Hire developers when the plugin touches payments, user data, or third-party APIs; when it must pass a security audit; or when downtime has a dollar cost. Freelance WordPress developers typically bill $20 to $100 per hour in the US market, and a professionally built custom plugin usually lands between $1,500 and $15,000 depending on complexity.

A useful middle path: build the prototype yourself to validate the idea, then bring in a team to harden, test, and maintain it.

Get a Custom WordPress Plugin Built Right

XCEEDBD designs, builds, and maintains custom WordPress plugins for businesses across the US and worldwide: secure, update-safe, and built to the same standards the WordPress.org review team enforces. Whether you need a single integration or a full product, our developers ship code you will not have to apologize for later.

Book a free consultation and tell us what your site should do that it does not do today.

FAQs

How long does it take to learn WordPress plugin development?

With existing PHP knowledge, most developers ship a working simple plugin within a week and reach directory-submission quality in 1 to 3 months. Starting from zero programming experience, plan on 4 to 6 months of steady practice.

What skills do I need to develop a WordPress plugin?

PHP is the core requirement, plus basic HTML, CSS, and MySQL. JavaScript and React matter only if you build interactive editor blocks; since WordPress 7.0, simple blocks can be registered with PHP alone.

Do I need to license my WordPress plugin?

If you distribute it publicly or submit it to the WordPress.org directory, it must use a GPLv2-or-later compatible license. Plugins built purely for your own site or a single client can remain private with no directory licensing requirement.

Can I make money developing WordPress plugins?

Yes, through premium versions (freemium), paid add-ons, subscriptions, or client work. The WordPress economy is estimated at $596.7 billion, and successful premium plugins commonly price between $29 and $299 per year per site.

What is the difference between an action hook and a filter hook?

An action runs your code at a specific event and returns nothing. A filter receives data, must return data, and is used to modify values like post content or titles before WordPress uses them.

How do I test a WordPress plugin before publishing it?

Run the official Plugin Check plugin, test on a local wp-env or Playground environment with WP_DEBUG enabled, verify behavior on the oldest and newest PHP versions you support, and confirm clean uninstall behavior.

Does WordPress 7.0 break existing plugins?

Most well-maintained plugins work fine, but 7.0 enforces the iframed editor for modern blocks and drops PHP 7.2 and 7.3 support, so plugins relying on parent-window JavaScript globals or ancient PHP need updates. Always test in staging first.

How much does custom WordPress plugin development cost?

Simple plugins run roughly $500 to $2,500, mid-complexity builds $2,500 to $8,000, and complex plugins with integrations, payments, or heavy security requirements $8,000 to $15,000 or more. Hourly rates for experienced WordPress developers range from $20 to $100 plus.

Wait! Before You Go...

Ready to Scale Your Digital Presence?

Discover how XCEEDBD’s custom software and premium design solutions can accelerate your business growth and maximize your ROI.