A modern WordPress plugin boilerplate by SolveBeam, providing a structured foundation for building scalable and maintainable plugins.
- PHP 8.2+
- WordPress 6.7+
- Composer
- Node.js / npm
composer install
npm installnpx wp-env start
npx wp-env stopThe .wp-env.json maps the plugin twice into the WordPress environment:
| Mount path | Source | Purpose |
|---|---|---|
wp-content/plugins/solvebeam-boilerplate-dev |
./ |
Live development (including dev files) |
wp-content/plugins/solvebeam-boilerplate |
./build/stage-2/ |
Built distribution version |
This lets you test both the raw source and the production build side-by-side.
composer run buildThe build uses a two-stage rsync process:
- Stage 1 — copies source (respecting
.distignore), then runscomposer install --no-devto get production-only dependencies. - Stage 2 — copies stage 1 output (again respecting
.distignore) to strip any remaining dev artifacts, then generates.pot/.motranslation files and creates a dist archive viawp dist-archive.
The final distributable ZIP is created from build/stage-2/.
composer run phpcs
composer run rectorThis boilerplate follows the SolveBeam Plugin Development Guidelines. Key conventions that may not be immediately obvious:
WordPress plugins typically contain PHP, JavaScript, CSS, and other assets. Using src/ for only PHP files creates ambiguity about where non-PHP source files belong. The psr-4/ directory makes the PSR-4 autoload root explicit and prevents accidental mixing of PHP and non-PHP sources.
Every PHP file must start with declare(strict_types=1); — no exceptions.
All classes live directly under a single namespace (e.g. SolveBeam\WordPressPluginBoilerplate). No sub-namespaces, no deep folder structure. Everything goes into psr-4/ directly.
- Classes →
finalwherever possible - Properties →
private readonlywherever possible - Methods →
privatewherever possible - Only expose what must be public
psr-4/Plugin.php must be final, use a private constructor, and expose a single public static function instance(): self entry point. Hooks are registered internally from the constructor.
Always use PHP 8.1+ first-class callable syntax for hook callbacks:
// ✅ Correct
add_action( 'init', $this->init( ... ) );
// ❌ Never use array syntax
add_action( 'init', [ $this, 'init' ] );No redundant or obvious comments. Only add comments where the logic isn't self-evident.
The .distignore file ensures development-only files (config files, build tooling, node_modules, etc.) are excluded from the production ZIP. A .gitattributes with export-ignore rules should be used to keep GitHub-generated ZIP archives clean as well.
solvebeam-boilerplate/
├── solvebeam-boilerplate.php # Main plugin file (bootstrap)
├── composer.json
├── package.json
├── .wp-env.json
├── .editorconfig
├── .gitattributes
├── .distignore
├── README.md
├── CHANGELOG.md
├── phpcs.xml.dist
├── rector.php
├── psr-4/
│ └── Plugin.php # Singleton entry point
├── languages/
├── assets/
│ ├── js/
│ └── css/
└── vendor/
GPL-2.0-or-later