How to Create a WordPress Plugin from Scratch: Ultimate Beginner's Guide 2026

4 weeks ago · Updated 4 weeks ago

Want to unlock the full power of WordPress? Learning to build your own plugins is one of the most valuable skills for any WordPress user, developer, or freelancer. Plugins extend WordPress functionality without touching core files, allowing custom features like forms, dashboards, shortcodes, or integrations—all while keeping your site lightweight and secure.

This comprehensive 2026 beginner tutorial (over 3000 words) walks you through creating a simple yet functional WordPress plugin from zero. No advanced frameworks needed—just basic PHP knowledge, a local WordPress setup, and curiosity. We'll cover structure, hooks, shortcodes, admin pages, forms with data storage, security best practices, packaging for distribution, and next steps for advanced development.

Whether you're customizing for clients, solving specific problems, or aiming to sell on marketplaces like CodeCanyon, this guide gives you a solid foundation.

What Is a WordPress Plugin?

A WordPress plugin is a PHP file (or folder of files) that adds new features to WordPress. It runs alongside the core without modifying it, thanks to the plugin API.

  • Installed in /wp-content/plugins/
  • Activated/deactivated from the admin dashboard
  • Uses hooks (actions & filters) to inject code at specific points

Plugins can do almost anything: contact forms, SEO tools, custom post types, e-commerce add-ons, or simple text injections.

Why Build Your Own Plugin?

Even with 60,000+ free plugins in the repository:

  1. Exact Customization — Create precisely what you need, no bloat from third-party plugins.
  2. Better Performance — Only include required code; avoid loading unused features.
  3. Deeper WordPress Knowledge — Master hooks, actions, filters, the Options API, nonces, and more.
  4. Security & Control — Avoid vulnerabilities in outdated plugins; ensure your code follows best practices.
  5. Income Potential — Sell premium plugins or offer custom development services.

Who Is This Tutorial For?

  • Beginners with basic PHP (variables, functions, loops, conditionals)
  • WordPress users familiar with installing themes/plugins and the dashboard
  • Developers wanting practical, hands-on plugin creation

If you're new to PHP or WordPress structure, start with free resources like the WordPress Codex or beginner PHP tutorials.

Step 1: Development Environment Setup

Don't code on a live site—use a local setup.

Recommended Tools (2026):

  • Local Server:
    • LocalWP (free, modern, visual dashboard – best for beginners)
    • XAMPP / MAMP / Laragon (classic stack with PHP 8.2+ and MySQL)
  • Code Editor:
    • Visual Studio Code (free, extensions like PHP Intelephense, WordPress snippets)
    • PhpStorm (pro-level, great debugging)
  • Browser: Chrome/Firefox with dev tools open
  • WordPress: Latest version (6.7+ in 2026) installed locally

Install WordPress locally → create a test site → you're ready!

Step 2: Basic Plugin Structure

All plugins start simple.

  1. Navigate to /wp-content/plugins/
  2. Create a new folder: my-first-plugin (use hyphens/lowercase, descriptive name)
  3. Inside the folder, create the main file: my-first-plugin.php

Add the Plugin Header (required for WordPress to recognize it):

PHP
<?php
/**
 * Plugin Name:       My First Plugin
 * Plugin URI:        https://example.com/my-first-plugin
 * Description:       A simple beginner plugin to learn WordPress development.
 * Version:           1.0.0
 * Author:            Your Name
 * Author URI:        https://yourwebsite.com
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       my-first-plugin
 */

Save → refresh Plugins page in admin → activate!

Security Tip: Add this at the top of every PHP file:

PHP
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

Step 3: Your First Feature – Add Text to Footer (Using Hooks)

Hooks are WordPress magic: Actions run code at specific moments; Filters modify data.

We'll use wp_footer action to inject text.

Add to my-first-plugin.php:

PHP
add_action( 'wp_footer', 'mfp_add_footer_text' );

function mfp_add_footer_text() {
    echo '<p style="text-align: center; color: #666; font-size: 14px; margin-top: 20px;">Powered by My First Plugin – Learning WordPress in 2026!</p>';
}
  • add_action() attaches your function to the hook.
  • Visit any frontend page → scroll to bottom → see the text!

Experiment: Try wp_head for header injection or the_content filter to modify post content.

Step 4: Create a Simple Shortcode

Shortcodes let users add dynamic content via [shortcode] in posts/pages.

Add:

PHP
add_shortcode( 'hello_world', 'mfp_hello_shortcode' );

function mfp_hello_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'name' => 'World',
    ), $atts );

    return '<div style="padding: 15px; background: #f9f9f9; border: 1px solid #ddd; border-radius: 5px;">Hello, ' . esc_html( $atts['name'] ) . '!</div>';
}

Usage: [hello_world name="Bersimu"] → outputs a styled greeting.

Pro Tip: Always esc_html() or esc_attr() output for security.

Step 5: Add an Admin Menu Page

Plugins often need settings pages.

Add:

PHP
add_action( 'admin_menu', 'mfp_add_admin_menu' );

function mfp_add_admin_menu() {
    add_menu_page(
        'My First Plugin Settings',      // Page title
        'My Plugin',                     // Menu title
        'manage_options',                // Capability (admin only)
        'my-first-plugin',               // Slug
        'mfp_settings_page',             // Callback
        'dashicons-admin-generic',       // Icon
        80                               // Position
    );
}

function mfp_settings_page() {
    ?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
        <p>Welcome to your custom plugin settings page!</p>
    </div>
    <?php
}

Activate → see new menu in sidebar!

Step 6: Build a Settings Form & Save Data (Options API)

Use WordPress Options API to store/retrieve data safely.

Update settings page:

PHP
function mfp_settings_page() {
    if ( isset( $_POST['mfp_save'] ) && check_admin_referer( 'mfp_nonce' ) ) {
        $name = sanitize_text_field( $_POST['mfp_name'] ?? '' );
        update_option( 'mfp_user_name', $name );
        echo '<div class="notice notice-success"><p>Settings saved!</p></div>';
    }

    $saved_name = get_option( 'mfp_user_name', 'Guest' );
    ?>
    <div class="wrap">
        <h1>My Plugin Settings</h1>
        <form method="post">
            <?php wp_nonce_field( 'mfp_nonce' ); ?>
            <table class="form-table">
                <tr>
                    <th><label for="mfp_name">Your Name</label></th>
                    <td><input type="text" name="mfp_name" id="mfp_name" value="<?php echo esc_attr( $saved_name ); ?>" class="regular-text"></td>
                </tr>
            </table>
            <p><input type="submit" name="mfp_save" class="button button-primary" value="Save Changes"></p>
        </form>
    </div>
    <?php
}
  • Nonce for CSRF protection
  • Sanitize input, escape output
  • update_option() / get_option() store in wp_options table

Step 7: Essential Security Best Practices (2026 Standards)

  1. Direct Access Prevention: if ( ! defined( 'ABSPATH' ) ) exit;
  2. Input Sanitization: sanitize_text_field(), intval(), etc.
  3. Output Escaping: esc_html(), esc_attr(), esc_url()
  4. Nonces: Always on forms (wp_nonce_field() + wp_verify_nonce())
  5. Capability Checks: current_user_can( 'manage_options' )
  6. Prefix Everything: Functions/options like mfp_... to avoid conflicts
  7. No Raw Queries: Use $wpdb->prepare() if needed

Step 8: Package & Install Your Plugin

  1. Ensure structure:
    text
    my-first-plugin/
    └── my-first-plugin.php
  2. Zip the folder (not just the file): Right-click → Compress → my-first-plugin.zip
  3. On any WordPress site: Plugins → Add New → Upload Plugin → Install & Activate

Congratulations—you've built and deployed a real plugin!

Next Steps & Advanced Topics

  • Custom Post Types (CPT) & Taxonomies
  • Settings API for better forms
  • AJAX for dynamic features
  • Gutenberg Blocks
  • Enqueue scripts/styles properly
  • Internationalization (i18n)
  • Submit to WordPress.org repository

Resources (2026):

  • Official Plugin Handbook: developer.wordpress.org/plugins
  • Advanced Custom Fields (ACF) tutorials for fields
  • Toptal / WP Engine guides for best practices

Start small, experiment locally, and iterate. Your first plugin is just the beginning—soon you'll build powerful tools!

Ready to code? Create your folder now and follow along. Questions on any step? Drop them below!


WordPress Plugin Development FAQ: Common Questions Answered for Beginners (2026 Edition)


Here are the most frequently asked questions by beginners starting to create their own WordPress plugins in 2026. These answers are practical, up-to-date, and based on the latest WordPress standards (PHP 8.1+, WP 6.7+).

1. Do I need to be an expert PHP developer to create a WordPress plugin?

No — basic PHP knowledge is enough for your first plugin. You should understand variables, functions, arrays, conditionals (if/else), and loops. Most beginner plugins use simple WordPress functions like add_action(), add_shortcode(), update_option(), etc. Advanced topics (OOP, classes, AJAX) can come later.

2. What's the minimum WordPress and PHP version required in 2026?

  • WordPress: 6.5 or higher (recommended 6.7+ for best compatibility)
  • PHP: 8.1 or higher (WordPress officially recommends 8.2 or 8.3 in 2026 for security & performance)

Always check Requires PHP and Requires at least in your plugin header.

3. Can I create a plugin with just one file?

Yes — the simplest plugins are single PHP files. WordPress only needs a valid plugin header and your code in that file. As your plugin grows (shortcodes, admin pages, assets), it's better to organize into multiple files/folders.

4. Why does my plugin not appear in the Plugins list?

Common reasons:

  • Missing or incorrect plugin header (Plugin Name is required)
  • File saved in wrong location (must be directly in /wp-content/plugins/your-plugin-folder/)
  • Syntax error in PHP → check debug.log or enable WP_DEBUG
  • Folder/file permissions issue on server

5. What is the difference between action hooks and filter hooks?

  • Action hooks: Run code at a specific point (e.g., wp_footer, admin_menu). Use add_action(). No return value needed.
  • Filter hooks: Modify data before it's used/displayed (e.g., the_content, the_title). Use add_filter(). Must return the modified value.

Example: add_action('wp_footer', 'my_function'); → adds something add_filter('the_content', 'my_filter_function'); → changes content

6. How do I make my shortcode accept parameters?

Use shortcode_atts() to define defaults and merge user attributes:

PHP
add_shortcode('greeting', function($atts) {
    $atts = shortcode_atts(['name' => 'Guest'], $atts);
    return 'Hello, ' . esc_html($atts['name']) . '!';
});

Usage: [greeting name="Bersimu"]

7. Why should I always use nonces on forms?

Nonces protect against CSRF attacks (someone tricking a logged-in user into submitting a form). WordPress makes it easy:

PHP
wp_nonce_field('my_action', 'my_nonce');

Validate on submit:

PHP
if (!isset($_POST['my_nonce']) || !wp_verify_nonce($_POST['my_nonce'], 'my_action')) {
    wp_die('Security check failed.');
}

8. How do I safely save and retrieve plugin settings?

Use the Options API:

  • Save: update_option('my_plugin_key', $value);
  • Retrieve: get_option('my_plugin_key', 'default_value');

Always sanitize input before saving:

PHP
$value = sanitize_text_field($_POST['my_field']);
update_option('my_plugin_key', $value);

And escape on output: esc_html(get_option('my_plugin_key'))

9. Should I create a custom database table for my plugin?

Not for simple plugins. Use wp_options table for settings (via Options API). Only create custom tables for large datasets (e.g., thousands of records like user submissions, logs). Use $wpdb->prepare() for queries.

10. How do I prevent my plugin from conflicting with others?

  • Prefix all functions, classes, variables, options, hooks: e.g., bersimu_ or mcp_
  • Use unique text domain for translations: 'my-custom-plugin'
  • Avoid global variables; use classes if possible
  • Enqueue scripts/styles only when needed (wp_enqueue_script with proper dependencies)

11. How do I add CSS or JavaScript to my plugin?

Use wp_enqueue_style() and wp_enqueue_script():

PHP
add_action('wp_enqueue_scripts', 'mcp_enqueue_assets');

function mcp_enqueue_assets() {
    wp_enqueue_style('mcp-style', plugin_dir_url(__FILE__) . 'assets/style.css');
    wp_enqueue_script('mcp-script', plugin_dir_url(__FILE__) . 'assets/script.js', ['jquery'], '1.0', true);
}

For admin-only: use admin_enqueue_scripts.

12. Can I sell or submit my plugin to WordPress.org?

Yes — both are possible.

  • WordPress.org repository: Free plugins only. Follow Plugin Guidelines, add readme.txt, use SVN.
  • Premium (sell): CodeCanyon, your own site, Gumroad. Use your own licensing system (e.g., Easy Digital Downloads).

13. My plugin breaks the site (white screen of death). How to fix?

  1. Enable debugging in wp-config.php:
    PHP
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
  2. Check /wp-content/debug.log for errors.
  3. Common causes: syntax error, missing semicolon, wrong hook name, undefined function.

14. How do I make my plugin translatable (multilingual)?

  1. Add text domain in header: Text Domain: my-custom-plugin
  2. Wrap strings: esc_html__('Hello World', 'my-custom-plugin')
  3. Load translations: load_plugin_textdomain('my-custom-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages/');
  4. Create .pot file with tools like Poedit.

15. Where can I learn more after this beginner tutorial?

  • Official: developer.wordpress.org/plugins
  • WordPress Plugin Handbook (updated 2026)
  • YouTube: "WPBeginner", "Ferdy Korpershoek", "WPCrafter" channels
  • Communities: Reddit r/Wordpress, WordPress.org forums, Facebook groups
  • Books: "Professional WordPress Plugin Development" (updated editions)

Leave a Reply

Your email address will not be published. Required fields are marked *

Go up