WP Apps is an open spec for sandboxed, permission-scoped WordPress extensions. Apps run as isolated services with zero runtime cost — they write data via API, WordPress renders it. No database access, no filesystem access, no PHP execution. The Shopify model, for WordPress.
Every plugin gets full, unrestricted access to everything. A single vulnerable plugin compromises the entire site.
Plugin vulnerabilities are the #1 attack vector for WordPress sites. Not because developers are careless — because the architecture gives every extension the keys to everything.
Apps write data via API, WordPress renders it. No HTTP calls during page loads. No PHP executing in your process. No performance penalty.
Apps run anywhere — a cloud server, a container, a serverless function, or even a separate process on the same machine. They never run inside WordPress.
Apps ship a wp-app.json declaring identity, scopes, event subscriptions, and blocks. The admin reviews and approves before installation.
Apps get scoped, short-lived access tokens (1hr) with automatic refresh. No database credentials, no filesystem paths, no PHP runtime sharing.
When a post is saved, user registers, or content changes — apps get an async webhook. They process in the background and write results back via API. Page loads are never blocked.
Apps register blocks that the admin places via the block editor. Assets load only where the block appears. Works in Gutenberg, Elementor (via shortcode fallback), and Classic Editor.
Block renders are cached. Post meta is served from WordPress's cache layer. A site with 20 apps installed loads at the same speed as a site with zero apps.
Apps add zero overhead to frontend page loads. Data is written at save time and served from cache. No HTTP round-trips during rendering.
Scopes like posts:read, users:read:basic, email:send. Apps declare what they need; admins approve exactly that. Never-grantable capabilities protect secrets.
Apps subscribe to WordPress events (save_post, user_register, etc.) and process them in the background. Never blocking, always fire-and-forget.
Apps register Gutenberg blocks with automatic shortcode fallback for Elementor, Divi, and Classic Editor. Block output is cached — rendered once, served forever.
Apps store settings and business data in their own database. WordPress is used only for post meta (namespaced, per-app) when data is tied to a specific post.
Every API call, webhook, and data access is rate-limited and logged. 1,000 reads/hr, 200 writes/hr, 50 emails/hr per app. Full visibility into what every app does.
Declare everything in a manifest. Handle events and blocks with a clean SDK. Ship anywhere that serves HTTP.
{
"app": {
"id": "com.example.my-seo-app",
"name": "My SEO App",
"version": "1.0.0"
},
"permissions": {
"scopes": ["posts:read", "postmeta:read", "postmeta:write"]
},
// Tier 1: Async event webhooks (zero page-load cost)
"hooks": {
"events": [
{ "event": "save_post", "description": "Analyze content and write SEO score to post meta" }
]
},
// Post meta rendered automatically in wp_head by the runtime
"postmeta": {
"seo_title": "SEO title override",
"seo_description": "Meta description",
"schema_json": "JSON-LD schema markup"
},
"surfaces": {
"blocks": [
{ "name": "my-seo-app/faq", "title": "FAQ (with Schema)", "cache_ttl": 3600 }
]
}
}
use WPApps\SDK\App; use WPApps\SDK\Request; use WPApps\SDK\Response; $app = new App(__DIR__ . '/wp-app.json'); // Event: analyze post on save (async, zero page-load cost) $app->onEvent('save_post', function (Request $req): Response { $postId = $req->args[0]; $post = $req->api->get("/apps/v1/posts/{$postId}"); $score = analyze_seo($post['content']); // Write to post meta — runtime renders in wp_head automatically $req->api->put("/apps/v1/posts/{$postId}/meta/seo_score", ['value' => $score]); $req->api->put("/apps/v1/posts/{$postId}/meta/schema_json", ['value' => '...']); return Response::ok(); }); // Block: render FAQ with schema (cached, served from WP cache layer) $app->onBlock('my-seo-app/faq', function (Request $req): Response { return Response::block('<div class="faq">...</div>'); }); $app->run();
# Scaffold a new app $ wp-apps init my-seo-app --language php # Validate your manifest $ wp-apps validate ./wp-app.json ✓ Manifest valid ✓ 3 scopes declared ✓ 1 event webhook ✓ 1 block registered # Run locally with tunnel to your dev site $ wp-apps dev --site https://mysite.com App running at localhost:3000 Tunnel: https://abc123.wp-apps.dev Connected to mysite.com ✓ # Deploy $ wp-apps deploy --platform instawp ✓ Deployed v1.0.0 to InstaWP Apps Platform
| Aspect | Traditional Plugin | WP App |
|---|---|---|
| Execution | In-process PHP | External HTTP service |
| Database | Full access ($wpdb, any table) | Scoped REST API only |
| Filesystem | Full (wp-config, core files) | None |
| Settings storage | wp_options (autoloaded, bloats every page) | App's own database |
| Frontend assets | CSS/JS on every page | Blocks — load only where placed |
| Page load impact | Adds PHP execution + queries + assets | Zero (data pre-written, cached) |
| Permissions | All or nothing | Granular scopes, admin-approved |
| Crash impact | Takes down entire site | App fails gracefully |
| Caching | Requires caching plugin | Built-in block + page cache |
| Audit trail | None | Full audit log, rate limits |
| GDPR | Plugin-dependent | Built-in privacy declarations + export/erasure |
Apps can run on the same server as WordPress — as a separate process. Same machine, separate runtime. Co-located apps add just 1–5ms latency per event webhook.
WP Apps is an open specification with a working reference implementation. Read the spec, try the SDK, build an app, and contribute.