Back to skills
SkillHub ClubAnalyze Data & AIFull StackFrontendBackend

wp-plugin-development

Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
923
Hot score
99
Updated
March 20, 2026
Overall rating
C4.9
Composite score
4.9
Best-practice grade
B84.8

Install command

npx @skill-hub/cli install wordpress-agent-skills-wp-plugin-development

Repository

WordPress/agent-skills

Skill path: skills/wp-plugin-development

Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging.

Open repository

Best for

Primary workflow: Analyze Data & AI.

Technical facets: Full Stack, Frontend, Backend, Data / AI, Security, Integration.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: WordPress.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install wp-plugin-development into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/WordPress/agent-skills before adding wp-plugin-development to shared team environments
  • Use wp-plugin-development for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: wp-plugin-development
description: "Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging."
compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."
---

# WP Plugin Development

## When to use

Use this skill for plugin work such as:

- creating or refactoring plugin structure (bootstrap, includes, namespaces/classes)
- adding hooks/actions/filters
- activation/deactivation/uninstall behavior and migrations
- adding settings pages / options / admin UI (Settings API)
- security fixes (nonces, capabilities, sanitization/escaping, SQL safety)
- packaging a release (build artifacts, readme, assets)

## Inputs required

- Repo root + target plugin(s) (path to plugin main file if known).
- Where this plugin runs: single site vs multisite; WP.com conventions if applicable.
- Target WordPress + PHP versions (affects available APIs and placeholder support in `$wpdb->prepare()`).

## Procedure

### 0) Triage and locate plugin entrypoints

1. Run triage:
   - `node skills/wp-project-triage/scripts/detect_wp_project.mjs`
2. Detect plugin headers (deterministic scan):
   - `node skills/wp-plugin-development/scripts/detect_plugins.mjs`

If this is a full site repo, pick the specific plugin under `wp-content/plugins/` or `mu-plugins/` before changing code.

### 1) Follow a predictable architecture

Guidelines:

- Keep a single bootstrap (main plugin file with header).
- Avoid heavy side effects at file load time; load on hooks.
- Prefer a dedicated loader/class to register hooks.
- Keep admin-only code behind `is_admin()` (or admin hooks) to reduce frontend overhead.

See:
- `references/structure.md`

### 2) Hooks and lifecycle (activation/deactivation/uninstall)

Activation hooks are fragile; follow guardrails:

- register activation/deactivation hooks at top-level, not inside other hooks
- flush rewrite rules only when needed and only after registering CPTs/rules
- uninstall should be explicit and safe (`uninstall.php` or `register_uninstall_hook`)

See:
- `references/lifecycle.md`

### 3) Settings and admin UI (Settings API)

Prefer Settings API for options:

- `register_setting()`, `add_settings_section()`, `add_settings_field()`
- sanitize via `sanitize_callback`

See:
- `references/settings-api.md`

### 4) Security baseline (always)

Before shipping:

- Validate/sanitize input early; escape output late.
- Use nonces to prevent CSRF *and* capability checks for authorization.
- Avoid directly trusting `$_POST` / `$_GET`; use `wp_unslash()` and specific keys.
- Use `$wpdb->prepare()` for SQL; avoid building SQL with string concatenation.

See:
- `references/security.md`

### 5) Data storage, cron, migrations (if needed)

- Prefer options for small config; custom tables only if necessary.
- For cron tasks, ensure idempotency and provide manual run paths (WP-CLI or admin).
- For schema changes, write upgrade routines and store schema version.

See:
- `references/data-and-cron.md`

## Verification

- Plugin activates with no fatals/notices.
- Settings save and read correctly (capability + nonce enforced).
- Uninstall removes intended data (and nothing else).
- Run repo lint/tests (PHPUnit/PHPCS if present) and any JS build steps if the plugin ships assets.

## Failure modes / debugging

- Activation hook not firing:
  - hook registered incorrectly (not in main file scope), wrong main file path, or plugin is network-activated
- Settings not saving:
  - settings not registered, wrong option group, missing capability, nonce failure
- Security regressions:
  - nonce present but missing capability checks; or sanitized input not escaped on output

See:
- `references/debugging.md`

## Escalation

For canonical detail, consult the Plugin Handbook and security guidelines before inventing patterns.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/structure.md

```markdown
# Plugin structure and loading

Use this file when introducing or refactoring a plugin architecture.

## Core concepts

- Main plugin file contains the plugin header and bootstraps the plugin.
- Prefer predictable init:
  - minimal boot file
  - a loader/class that registers hooks
  - admin-only code behind admin hooks

Upstream reference:

- https://developer.wordpress.org/plugins/plugin-basics/


```

### references/lifecycle.md

```markdown
# Activation, deactivation, uninstall

Use this file for lifecycle changes and data cleanup.

## Activation / deactivation hooks

- `register_activation_hook( __FILE__, 'callback' )`
- `register_deactivation_hook( __FILE__, 'callback' )`

Guardrails:

- These hooks must be registered at top-level (not inside other hooks).
- If you flush rewrite rules, ensure rules are registered first (often via a shared function called both on `init` and activation).

Upstream reference:

- https://developer.wordpress.org/plugins/plugin-basics/activation-deactivation-hooks/

## Uninstall

Preferred approaches:

- `uninstall.php` (runs only on uninstall)
- `register_uninstall_hook()`

Guardrails:

- Check `WP_UNINSTALL_PLUGIN` before running destructive cleanup.

Upstream reference:

- https://developer.wordpress.org/plugins/plugin-basics/uninstall-methods/


```

### references/settings-api.md

```markdown
# Settings API (admin options)

Use this file when adding settings pages or storing user-configurable options.

Core APIs:

- `register_setting()`
- `add_settings_section()`
- `add_settings_field()`

Upstream references:

- Settings API overview: https://developer.wordpress.org/plugins/settings/settings-api/
- Register settings: https://developer.wordpress.org/plugins/settings/registration/
- Add settings fields: https://developer.wordpress.org/plugins/settings/settings-fields/

Practical guardrails:

- Use `sanitize_callback` to validate/sanitize data.
- Use capability checks (commonly `manage_options`) for settings screens and saves.
- Escape values on output (`esc_attr`, `esc_html`, etc.).


```

### references/security.md

```markdown
# Security guardrails (plugin work)

Use this file when making security fixes or when handling any input/output.

## Nonces + permissions

- Nonces help prevent CSRF, not authorization.
- Always pair nonces with capability checks (`current_user_can()` or a more specific capability).

Upstream reference:

- https://developer.wordpress.org/apis/security/nonces/

## Sanitization and escaping

Golden rule:

- sanitize/validate on input, escape on output.

Practical rules:

- never process the entire `$_POST` / `$_GET` array; read explicit keys
- use `wp_unslash()` before sanitizing when needed
- use prepared statements for SQL; avoid interpolating user input into queries

Common review guidance:

- https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/


```

### references/data-and-cron.md

```markdown
# Data storage, cron, and upgrades

Use this file when adding persistent storage, background jobs, or upgrade routines.

## Data storage

- Prefer Options API for small config/state.
- Use custom tables only when needed; store schema version and provide upgrade paths.

## Cron

- Ensure tasks are idempotent (may run late or multiple times).
- Provide a manual trigger path for debugging (WP-CLI or admin-only action).

## Database safety note

If using `$wpdb->prepare()`, avoid building queries with concatenated user input.
Recent WordPress versions support identifier placeholders (`%i`) but you must not assume it exists without checking capabilities or target versions.


```

### references/debugging.md

```markdown
# Debugging quick routes

## Plugin doesn’t load / fatal errors

- Confirm correct plugin main file and header.
- Check PHP error logs and `WP_DEBUG_LOG`.
- If the repo is a site repo, confirm you edited the correct plugin under `wp-content/plugins/`.

## Activation hook surprises

- Hooks must be registered at top-level.
- Activation runs in a special context; avoid assuming other hooks already ran.

## Settings not saving

- Confirm `register_setting()` is called.
- Confirm the option group matches the form.
- Confirm capability checks and nonces.


```

wp-plugin-development | SkillHub