Building a WordPress plugin in 2026 still means stitching together half a dozen concerns before you write your first feature: PHP bootstrap, REST routes, asset pipelines, admin UI, i18n, release ZIPs, and (if you're lucky) some kind of dev proxy so you're not manually refreshing minified bundles.
I've done this enough times for client projects that I finally productized the scaffolding. It's called Vipresso — a GPL boilerplate you fork once, rename once, and ship from.
Try it in the browser (no install):
WordPress Playground demo
Repo: https://github.com/tommasomeli/vipresso
The problem I kept hitting
Most "WordPress + React" starters solve one layer well and leave you maintaining registration lists forever:
- You add a REST handler → edit a central routes file
- You add an admin tab → wire React Router manually
- You add a shortcode → hope visitors don't download your entire admin bundle
- You cut a release → hand-build a ZIP and pray the headers are correct
WordPress already has great primitives (capabilities, options, REST, hooks, cron, WP-CLI). What was missing, for me, was DX that respects those primitives while feeling like a normal Vite + TypeScript app.
What Vipresso actually is
Not a plugin you install on a site. A boilerplate repo you fork into your own product:
- React 19 + Vite + TypeScript admin SPA with HMR
- Real WordPress in Docker — Vite proxies everything except your bundle
- Auto-discovery on both sides — drop a file, no manual registration
-
Dual bundles —
app.js(admin) vsviewer.js(public shortcodes only) - Plop generators — routes, REST handlers, widgets, metaboxes, cron, WP-CLI
- Schema-driven settings — JSON schema → PHP store + React UI
- GitHub Actions — lint, Vitest, PHP syntax, Docker + Playwright smoke
- Release ZIP + in-plugin auto-updates from GitHub Releases
Fork → npm run plugin:rename -- YourPlugin → build features → npm run build:zip.
Architecture: two discovery systems, one repo
├── widgets/ # PHP + TSX + manifest.json
├── shortcodes/ # public-facing, viewer bundle only
├── metaboxes/
├── shared/ # settings.json + generated routes.json
├── src/ # React app (main.tsx + viewer.tsx)
└── plugin/ # WordPress plugin root (Bootstrap, Routes, Assets…)
Frontend: Vite import.meta.glob picks up pages, widgets, shortcodes.
Backend: Bootstrap.php scans for RouteProvider classes, cron jobs, WP-CLI commands.
In dev, feature folders are bind-mounted inside plugin/ so PHP and Node see identical paths. The release script copies them in before zipping.
REST without a registration file
Drop a class, implement RouteProvider, done:
final class BillingHandler implements \Vipresso\RouteProvider
{
public static function routes(): array {
return [
['/billing', \WP_REST_Server::READABLE, [self::class, 'list']],
['/billing', \WP_REST_Server::CREATABLE, [self::class, 'create'], null, [
'amount' => ['type' => 'number', 'required' => true],
'currency' => ['type' => 'string', 'enum' => ['EUR', 'USD']],
]],
];
}
}
From React: api.get<T>("/billing") — typed client, namespace from .env.
Keep handlers thin; push business logic into Actions/Services. WordPress coding conventions still apply.
Dual bundles matter
src/main.tsx → admin SPA, dashboard widgets, metaboxes.
src/viewer.tsx → shortcodes only.
Public visitors never download admin code. Obvious in hindsight, rarely default in starter templates.
Dev workflow
cp .env.example .env
pnpm install
docker compose up -d
pnpm run setup # WP install + plugin activation via wp-cli
pnpm run dev # Vite HMR on :3333, proxies WP on :8888
One .env drives PHP constants, Vite imports, Docker ports, and plugin.php / readme.txt headers (regenerated on every dev/build).
Live demo without a server
The Playground blueprint boots throwaway WordPress with the plugin pre-installed and admin auto-login — PHP-WASM in the browser, nothing on your infra:
npm run gen:playground # writes wp-playground-blueprint.json
Publish the blueprint JSON + release ZIP anywhere public; link from your README.
Who is this for?
- Agency devs shipping custom admin tools on WordPress
- Indie hackers who want WP's ecosystem (users, roles, posts, plugins) with modern frontend DX
- Teams tired of re-scaffolding the same release/REST/i18n plumbing
Not for: "I want a SaaS with auth and billing" — this is WordPress-native.
What's next
I'm using Vipresso as the base for client plugins and iterating in public. If you fork it, I'd love to hear what broke or what's missing.
- Issues / feature requests: GitHub
- Questions / ideas: GitHub Discussions
If this saves you a week of scaffolding, a ⭐ on the repo helps more than you'd think.
GPL v2+. Same license as WordPress. Fork it, rename it, ship it.
Top comments (0)