WordPress Playground is a full WordPress install that runs in the browser. PHP is compiled to WebAssembly (PHP.wasm), the database is SQLite, and the official limitations page puts the WASM files at 15 to 30 MB. There is no server, no wp-config.php to fill in, no MAMP, no Docker. You open a URL and you are inside wp-admin.
If you ship plugins or themes, run training, or do PR reviews, this changes a few daily workflows. If you run production sites, it does not replace them. Treat Playground as a sandbox and a demo tool, not a host.
Learn more about professional WordPress development at WPPoland.
What is WordPress Playground
Playground is an open-source WordPress project, released under GPLv2 or later. The web instance lives at playground.wordpress.net and the documentation at developer.wordpress.org/playground. The parts that matter in daily work:
- PHP.wasm runs PHP 7.4 through 8.5 inside a Web Worker. The Query API defaults to PHP 8.5; you pick another version per session with
?php=or a Blueprint - SQLite replaces MySQL through the official SQLite Database Integration plugin. Most plugins that use
$wpdbwork; code that hand-writes MySQL-specific SQL can fail - Browser storage keeps new Playgrounds as autosaves when saving is available. Playground keeps up to five recent autosaves, and a temporary Playground is gone after a refresh
- Mail and WP-CLI work in a sandboxed form.
wp_mail()messages land in the Email tool instead of an inbox, and the Terminal runs WP-CLI commands against the active site
Playground is a disposable WordPress instance you can hand someone over a URL. That is the whole product, and it is enough to be useful.
How WordPress Playground works
The architecture docs describe the boot sequence. The page on playground.wordpress.net loads remote.html in an iframe. That file starts a Worker Thread and a Service Worker. The Worker Thread starts PHP and fills a virtual filesystem with a WordPress build patched to run on SQLite. The Service Worker then intercepts every HTTP request from the WordPress iframe and forwards it to the Worker Thread, which renders the response.
How WebAssembly runs PHP in the browser
The team compiles the PHP interpreter to WebAssembly with Emscripten. According to the WebAssembly PHP overview, the build needs only a few patches; the larger job was writing a PHP API module in C plus a JavaScript class that passes request bodies, uploads and php://stdin into PHP. Every PHP version is a separate static .wasm file, so switching versions means the browser downloads a different binary.
The browser tab orchestrates everything. Closing or reloading it destroys the execution environment, which is why storage modes (covered below) matter so much.
How Playground replaces MySQL with SQLite
There is no WebAssembly build of MySQL that runs in a browser. Playground ships PHP with the native SQLite driver, and the SQLite Database Integration plugin intercepts MySQL queries and rewrites them in the SQLite dialect. The docs state that its 2.0 release lets WordPress on SQLite pass 99% of the WordPress unit test suite. The remaining gap is where custom plugin SQL tends to break.
How networking works inside Playground
WebAssembly code can only call JavaScript APIs, so PHP cannot open sockets directly. In the browser, Playground offers two transports: a fast one that turns wp_safe_remote_get calls into fetch() requests, and a slower one that parses the TLS traffic PHP starts and translates it into fetch(). Because every request ends up as a browser fetch(), the target server must allow cross-origin requests. The Query API docs require the Access-Control-Allow-Origin header on any file Playground imports from a URL.
How to use WordPress Playground
There are four entry points, from no code at all to full programmatic control.
Method 1: Using the official Playground website
Open playground.wordpress.net. A fresh WordPress loads, and the tools sit in the Dock at the bottom of the screen. The web instance guide lists its destinations:
- New: start from the Blueprint gallery, a public Blueprint URL, a new Blueprint, a pull request preview, a GitHub repository, or an imported
.zip - Playgrounds: switch between recent and saved Playgrounds
- Site Settings: WordPress version, PHP version, language, networking and multisite
- Blueprint, Database, Files, Logs: view and edit the current Blueprint, download the SQLite database, browse files and read PHP errors
- Export: download a
.zip, copy the original setup link, or export selected files to a GitHub pull request
PHP version and networking can change on an existing stored Playground. WordPress version, language and multisite change the installation itself, so they start a fresh Playground. For block themes, landingPage: /wp-admin/site-editor.php in a Blueprint opens the Site Editor straight away.
Method 2: Embedding Playground in your website
Every option of the Query API is a URL parameter, so an iframe is enough for an embedded demo:
<iframe
src="https://playground.wordpress.net/?plugin=gutenberg&url=/wp-admin/post-new.php&mode=seamless"
width="100%"
height="800px"
frameborder="0"
allow="clipboard-write"
></iframe>The parameters you will use most, as documented in the Query API reference:
| Parameter | Description | Example values |
|---|---|---|
php | PHP version, default 8.5 | 7.4 to 8.5, latest, next |
wp | WordPress version, default latest | 6.9, latest, nightly, beta |
theme | Installs a theme from the WordPress.org directory | pendant, twentytwentyfive |
plugin | Installs a plugin; repeat it for several | gutenberg, woocommerce |
url | First page to open, default /wp-admin/ | /wp-admin/plugins.php |
mode | Browser UI or full width | browser-full-screen, seamless |
blueprint-url | Loads a Blueprint from a URL | https://example.com/blueprint.json |
storage | temp discards the site on refresh or close | temp |
language | Locale, needs networking | de_DE, pl_PL |
multisite | WordPress multisite mode | yes, no |
Installing a plugin or theme through the URL logs the visitor in as an admin. The lazy parameter defers loading until someone clicks “Run”, which keeps a page with an embed light until the visitor actually wants the demo.
Method 3: Using the Playground API for advanced integration
The JavaScript client from the @wp-playground/client npm package gives you full control from your own page, tests or CI/CD pipelines:
import { startPlaygroundWeb } from '@wp-playground/client';
async function initializePlayground() {
const client = await startPlaygroundWeb({
iframe: document.getElementById('wp-playground'),
remoteUrl: 'https://playground.wordpress.net/remote.html',
blueprint: {
landingPage: '/wp-admin/',
preferredVersions: {
php: '8.3',
wp: 'latest'
},
steps: [
{
step: 'installPlugin',
pluginData: {
resource: 'wordpress.org/plugins',
slug: 'gutenberg'
}
},
{
step: 'installTheme',
themeData: {
resource: 'wordpress.org/themes',
slug: 'twentytwentyfive'
}
}
]
}
});
return client;
}Method 4: Blueprint configuration for reproducible environments
Blueprints are JSON files that set up a Playground instance. The Blueprint getting started page lists three ways to use one: paste it into the URL fragment, pass it to the JavaScript API, or reference a file with blueprint-url. Blueprints cannot execute arbitrary JavaScript, which is why running someone else’s Blueprint does not require trust in the author.
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/plugins.php",
"preferredVersions": {
"php": "8.2",
"wp": "6.8"
},
"features": {
"networking": true
},
"steps": [
{
"step": "login",
"username": "admin",
"password": "password"
},
{
"step": "installPlugin",
"pluginData": {
"resource": "wordpress.org/plugins",
"slug": "query-monitor"
},
"options": {
"activate": true
}
},
{
"step": "setSiteOptions",
"options": {
"blogname": "My Test Site",
"blogdescription": "Testing WordPress Playground"
}
}
]
}The $schema line gives you autocompletion and validation in an editor. Per the data format docs, preferredVersions.wp accepts the last seven major releases (6.3 to 6.9 as of April 2026) plus latest, beta and nightly, and features.networking must stay on if the visitor should install plugins or themes.
How to run WordPress Playground locally with the CLI
The same runtime works in Node.js. The Playground CLI (@wp-playground/cli) needs Node.js 20.18 or newer and replaces the deprecated wp-now package.
cd my-plugin
npx @wp-playground/cli@latest startstart detects whether the folder is a plugin, theme or full WordPress install, mounts it, logs you in and opens the browser. The site persists between sessions in ~/.wordpress-playground/sites/<path-hash>/, and --reset gives you a clean install. server is the advanced command with manual control over mounts and storage, meant for custom setups and CI. Both accept --wp=, --php= and --blueprint=; the CLI defaults to PHP 8.3.
The CLI also has a php subcommand. The PHPUnit guide runs a plugin’s test suite against a clean WordPress on every run, with no local database:
npx @wp-playground/cli@latest php \
--auto-mount --php=8.1 --wp=6.5 \
-- \
/wordpress/wp-content/plugins/MY_PLUGIN/vendor/bin/phpunit \
-c /wordpress/wp-content/plugins/MY_PLUGIN/phpunit.xml.distThat makes a PHP and WordPress version matrix a loop over two flags instead of a set of Docker images.
What WordPress Playground is used for
Five workflows where Playground replaces something you used to do the slow way.
How to add a “try this plugin” demo link to a sales page
Instead of “download the zip, install on a staging site,” your CTA opens a Blueprint URL with your plugin pre-installed and demo content seeded. The visitor lands on the right admin screen, already logged in. The pattern works because the setup step disappears for the visitor.
The Blueprint URL pattern: https://playground.wordpress.net/?blueprint-url=https://example.com/blueprint.json. Host the Blueprint JSON anywhere that sends the CORS header. Inside WordPress posts, the official WordPress Playground block embeds the same kind of demo, optionally with a live code editor.
How to preview plugin pull requests in Playground
The PR preview guide uses the WordPress/action-wp-playground-pr-preview@v3 action. With plugin-path: . (or theme-path: .) it adds a Preview button to the pull request description. A click opens Playground with the plugin or theme installed and activated from the PR branch.
Two constraints come from the docs. Everything Playground installs must sit at a public URL, so a private repository needs more than the default setup. And if the plugin needs Composer or an npm build, the action uses a two-workflow setup: a read-only build workflow and a publish workflow that uploads the zip to a public ci-artifacts prerelease. The guide warns against switching to pull_request_target to run PR code with write permissions.
WordPress Playground for training and courses
Each student gets an isolated WordPress instance from the same Blueprint. No “my XAMPP won’t start” messages on day one. The limitations page lists desktop Chrome, Firefox, Safari and Edge plus mobile Safari and Chrome as supported, which covers Chromebooks and locked-down corporate laptops where Docker is blocked. The trade-off: browser storage is not a backup, so anything students want to keep needs the export-as-zip step at the end of the session.
How to reproduce a customer bug with a Blueprint
A customer reports a bug on a specific WordPress version, plugin set and theme. You ship them a Blueprint URL with that exact stack. They confirm reproduction in their browser. You debug against the same Blueprint locally with the CLI. The bug ticket now contains a deterministic reproduction case instead of “works on my machine.”
How to test old WordPress versions in Playground
Since August 2026, the Site Settings panel has an “Include older versions” option. The make.wordpress.org announcement describes PHP 5.2.17 compiled to WebAssembly and browser boot support for WordPress 0.7 through 6.2. Playground pairs the runtime automatically: WordPress 0.7 to 4.9 locks to PHP 5.2, 5.0 to 6.2 locks to PHP 7.4, and 6.3 or newer uses the modern flow. For a plugin author, that turns an old compatibility report into a browser setting instead of a legacy server stack.
When not to use WordPress Playground
- Anything that must deliver real mail or run on a real cron schedule
- Load testing, since PHP.wasm runs in a Web Worker inside the browser tab
- Plugins that shell out to
exec(), write to absolute filesystem paths, or need PHP extensions Playground does not ship - Third-party API calls that need server-to-server auth, since browser CORS rules apply and most APIs do not allow
playground.wordpress.netas an origin
WordPress Playground limitations and performance
The limitations page is short and worth reading before you put Playground in front of customers.
How much browser storage Playground can use
Playground does not publish a fixed quota. Storage belongs to the browser, and the docs warn that storage pressure, private browsing, profile changes or clearing site data can remove saved Playgrounds. Media-heavy demos load faster and survive longer when large files come from a URL through a Blueprint step instead of being uploaded inside the session.
How long WordPress Playground takes to load
The official figures:
| Scenario | Typical load time |
|---|---|
| Fresh WordPress, no plugins | 5 to 10 seconds |
| With small plugins | 10 to 20 seconds |
| With large plugins such as WooCommerce | 30 to 60 seconds |
| On mobile devices | 1.5 to 2 times slower than desktop |
Plugin size, network speed (the WASM files are 15 to 30 MB), device memory and the browser all play a part. The docs name Chrome and Edge as the fastest and Safari as slightly slower.
Is WordPress Playground slower than a real server
Yes, for CPU-heavy work. The architecture docs call the PHP server slow enough that it must run in a Web Worker, or every request would freeze the page. Image processing, bulk imports and large queries take noticeably longer than on a native PHP host, so do not benchmark plugin performance in Playground.
Which iframe quirks affect Playground demos
WordPress renders inside an iframe. Links with target="_top" reload the whole page you are working on, and JavaScript popups started inside the iframe may not appear. If your plugin opens OAuth windows or uses window.top, test the demo flow by hand.
Is WordPress Playground safe for real data
The official docs describe Playground as running entirely client-side, with no backend and no authentication. The site you build stays in your browser, so the risk sits on the device.
Does WordPress Playground save your data
The docs define three storage modes:
- Autosaved: stored in browser storage, kept only while it is one of the five most recent autosaves
- Saved: stored permanently in browser storage, or in a local directory in browsers that support the File System Access API
- Temporary: created with
?storage=tempor when saving is unavailable, discarded on refresh or when the tab closes
Security implications:
- Shared computers: autosaved and saved Playgrounds stay in that browser profile for the next user
- Sensitive data: do not enter real credentials or customer personal data
- Browser cleaning: clearing site data deletes saved Playgrounds
- Exports: “Download as .zip” exports files, database, plugins, themes and uploads, and New, Import zip restores it
Can WordPress Playground call external APIs
Networking is on by default (networking=yes in the Query API, features.networking: true in Blueprints). With it off, wp_safe_remote_get and similar functions fail immediately. With it on, requests go through the browser, so CORS decides what works. Use test credentials for any external service in a public demo, because the API key sits in a browser anyone can inspect.
What changed in WordPress Playground in 2026
The team posts updates on make.wordpress.org/playground. Four changes from 2026 matter for the workflows above:
- New interface (July 2026): the Dock replaced the earlier sidebars and modals. It grew out of the Playground table at the WordCamp Europe 2026 Contributor Day in Kraków
- Legacy versions (August 2026): WordPress 0.7 to 6.2 boot in the browser with automatic PHP pairing
- Terminal (September 2026): Dev Tools, Terminal runs PHP snippets with WordPress loaded and WP-CLI commands against the active site; WP-CLI downloads on first use
- Email tool (September 2026): messages sent through
wp_mail()are captured and shown with subject, sender, recipient and body. A captured email is not a delivered one, and plugins that send through their own SMTP connection or provider API bypass the capture
The docs also cover AI coding agents: a wp-playground agent skill and a WebMCP bridge. I cover that side in WordPress Playground and MCP for AI agents.
Common WordPress Playground Blueprint errors
A few traps that bite once you put Playground in front of real users.
PHP version drift. Your production host runs PHP 8.1. The Query API defaults to PHP 8.5. A demo passes; the customer installs your plugin on their site and hits a fatal error on a function your demo never exercised on 8.1. Pin preferredVersions.php to your minimum supported version, not the latest.
Temporary storage in embeds. An embed with storage=temp or can-save=no loses everything on refresh. That is right for a disposable demo and wrong for a training exercise. If the demo needs files, seed them with a writeFile step on every run.
CORS on imports and APIs. blueprint-url, import-site zips and PHP extension manifests all need the Access-Control-Allow-Origin header on the server that hosts them. A Blueprint that works from GitHub raw URLs can fail from your own CDN until you add the header.
Step ordering. Shorthands such as plugins, login, siteOptions and constants are expanded before the steps array. If one action must happen before another, write both as explicit steps in the order you need.
Mixed plugin shapes. The current installPlugin step uses pluginData, with activate inside options. Older examples use the deprecated pluginZipFile, and the docs say not to mix the two. A slug written into the resource (wordpress.org/plugins/woocommerce) is wrong as well: the resource needs a separate slug.
SQLite vs MySQL syntax. The translation layer covers almost all of core, but custom SQL in a plugin is your responsibility. Test the Blueprint with your full plugin and its real data paths, not just core.
WordPress Playground JSON-LD schema example
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "WordPress Playground: The Future of Testing and Demos",
"description": "Learn how to use WordPress Playground to run WP in the browser via WebAssembly. A complete guide for 2026 testing and demos.",
"author": {
"@type": "Organization",
"name": "WPPoland"
},
"datePublished": "2026-01-29",
"dateModified": "2026-10-14",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://wppoland.com/en/wordpress-playground-guide-2026/"
}
}{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to Use WordPress Playground for Testing and Development",
"description": "Step-by-step guide to running WordPress in your browser using WebAssembly technology",
"totalTime": "PT15M",
"supply": [
"Modern web browser",
"Internet connection"
],
"tool": [
{
"@type": "HowToTool",
"name": "Web Browser"
}
],
"step": [
{
"@type": "HowToStep",
"position": 1,
"name": "Access WordPress Playground",
"text": "Navigate to playground.wordpress.net in your browser to access the official WordPress Playground instance.",
"url": "https://playground.wordpress.net"
},
{
"@type": "HowToStep",
"position": 2,
"name": "Configure Your Environment",
"text": "Open Site Settings in the Dock and choose the WordPress version, PHP version, language and networking."
},
{
"@type": "HowToStep",
"position": 3,
"name": "Wait for the Instance",
"text": "A fresh WordPress without plugins typically loads in 5 to 10 seconds; large plugins such as WooCommerce take 30 to 60 seconds."
},
{
"@type": "HowToStep",
"position": 4,
"name": "Begin Testing",
"text": "Access the WordPress admin panel, install additional plugins, create content, and experiment with features in the isolated environment."
},
{
"@type": "HowToStep",
"position": 5,
"name": "Save or Export Your Work",
"text": "Use Export to download the site as a zip, or Store permanently to keep it in browser storage."
}
]
}{
"@context": "https://schema.org",
"@type": "QAPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is WordPress Playground suitable for production websites?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No, WordPress Playground is designed for testing, development, and educational purposes only. It runs in the visitor's browser and keeps data in browser storage."
}
},
{
"@type": "Question",
"name": "Can I migrate a Playground instance to a live server?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Export downloads a zip with files, database, plugins, themes and uploads. The database is SQLite, so moving to a MySQL host needs a migration step."
}
},
{
"@type": "Question",
"name": "Does Playground support all WordPress plugins and themes?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Most plugins and themes work correctly, but some may have compatibility issues due to the SQLite database or PHP-WASM environment. Plugins requiring specific server configurations or binary extensions may not function."
}
}
]
}A Playground Blueprint is the quickest way to show a client a plugin without asking for a server, a database or credentials. I build demos like that as part of WordPress plugin development.







