Want to build a WordPress plugin but not sure where to start? You are in the right place. I have shipped two plugins to the official directory, Word Counter Plus and Category Products Slider for WooCommerce. This guide is the checklist I wish I had on day one.

We will go from an empty folder to a plugin that is safe, fast and ready for WordPress.org. Each step is short. Also, every code sample works on a fresh install.

What you need before you build a WordPress plugin

You only need three things to create a WordPress plugin. First, a local WordPress site. Tools like LocalWP, DDEV or Docker all work well. Second, a code editor such as VS Code or PhpStorm. Third, basic PHP. Of course, you do not need to be an expert.

Also, turn on debug mode in wp-config.php. It shows notices that you would miss otherwise:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Now errors go to wp-content/debug.log. Keep that file open while you work.

Step 1: Create a WordPress plugin folder and main file

Each plugin lives in its own folder inside wp-content/plugins. Pick a unique slug, for example my-reading-time. Then add a PHP file with the same name, because WordPress looks for it there.

The top of that file is the plugin header. WordPress reads it to show your plugin in the admin:

<?php
/**
 * Plugin Name: My Reading Time
 * Description: Shows the reading time above each post.
 * Version:     1.0.0
 * Requires at least: 6.4
 * Requires PHP: 7.4
 * Author:      Your Name
 * License:     GPL-2.0-or-later
 * Text Domain: my-reading-time
 */

defined( 'ABSPATH' ) || exit;

The last line matters. It stops anyone from loading the file directly in a browser. Next, open Plugins in the admin. Your plugin is already there, so activate it.

Step 2: Learn hooks, the heart of WordPress plugin development

WordPress plugin development is mostly about hooks. A hook is a point where WordPress lets your code run. There are two kinds.

  • Actions run your code at a moment, such as init or wp_enqueue_scripts.
  • Filters receive a value, change it and return it, such as the_content.

For example, this filter adds a reading time above every post:

add_filter( 'the_content', function ( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() ) {
		return $content;
	}
	$words   = str_word_count( wp_strip_all_tags( $content ) );
	$minutes = max( 1, (int) ceil( $words / 220 ) );
	$label   = sprintf(
		/* translators: %d: minutes */
		_n( '%d min read', '%d min read', $minutes, 'my-reading-time' ),
		$minutes
	);
	return '<p class="mrt-time">' . esc_html( $label ) . '</p>' . $content;
} );

Notice the checks at the top. Without them, the text would also show in widgets and feeds. In short, always ask "where does this hook run?" before you use it.

Step 3: Organise the code as the plugin grows

One file is fine for a small plugin. However, real plugins grow fast. I use this layout for most projects:

my-reading-time/
├── my-reading-time.php   (header + bootstrap)
├── includes/             (PHP classes)
├── assets/               (CSS and JS)
├── languages/            (translations)
└── readme.txt            (WordPress.org listing)

Prefix everything that is global. That means functions, classes, options and CSS classes. Better yet, use a PHP namespace. As a result, your plugin will not clash with the other 59,000 plugins out there.

Also, load CSS and JS only where you need them. A slider script on every admin page slows down the whole site.

Step 4: Add a settings page

Most users expect a settings screen. Thankfully, the Settings API handles saving, nonces and error notices for you. So you write less code.

add_action( 'admin_init', function () {
	register_setting( 'mrt', 'mrt_words_per_minute', [
		'type'              => 'integer',
		'sanitize_callback' => 'absint',
		'default'           => 220,
	] );
} );

Then add the page with add_options_page() and render it with settings_fields() and do_settings_sections(). Keep the screen simple. In my experience, fewer options mean fewer support tickets.

Step 5: Make the plugin secure

Security is where most new plugins fail review. Still, the rules are short. Remember them as three verbs.

  1. Sanitize input. Clean every value you save, for example with sanitize_text_field() or absint().
  2. Escape output. Escape late, right where you print, with esc_html(), esc_attr() or esc_url().
  3. Verify intent. Check a nonce and the user's capability before any change, with check_admin_referer() and current_user_can().

For database queries, always use $wpdb->prepare(). Never put raw user input into SQL. As a result, you also avoid most issues that security scanners report.

Step 6: Make it fast and translation-ready

Speed is a feature. First, cache expensive work with the Transients API. Second, avoid queries inside loops. Third, check your plugin with Query Monitor. Then you can see every query and hook your code adds.

Next, wrap all text in translation functions like __() and esc_html_e(). Use your text domain every time. Volunteers on translate.wordpress.org can then translate your plugin for free.

Step 7: Publish your WordPress plugin on WordPress.org

When the plugin works, write a good readme.txt. It becomes your listing page. Therefore, treat it like a sales page. Explain the problem, show screenshots and answer common questions.

Before you submit, run the official Plugin Check tool. It catches most review issues in seconds. Then upload the ZIP on the Add Your Plugin page. Next, a volunteer reviews it, often within a few days to a few weeks.

After approval you get an SVN repository. Commit your code to trunk, tag a release and you are live. My WordPress.org profile lists both of my plugins if you want to see real listings.

Common mistakes when you build a WordPress plugin

  • Using generic names like get_settings() without a prefix.
  • Loading jQuery plugins on every page.
  • Saving data without sanitizing it.
  • Forgetting to clean up options on uninstall. Add an uninstall.php file for that.
  • Shipping without testing on the latest WordPress and PHP versions.

Final thoughts

In conclusion, to build a WordPress plugin well, you need a clean structure, the right hooks and strict security habits. So start small and solve one real problem. Then improve it with feedback from real users.

Need a custom plugin for your business, or a WooCommerce feature that no plugin covers? I build custom plugins for clients. See my services or get in touch. I am happy to help.