WordPress Playground: The full WordPress stack, now running in your browser
WordPress Playground looks like an ordinary site at first glance. It isn’t. The entire WordPress tech stack—PHP, database, and all—runs directly in the browser, with no cloud infrastructure in sight. You can use it freely at playground.wordpress.net, and because the site lives entirely client-side, nobody else can visit your instance. It's also ephemeral: refresh the page and it's gone. That makes it ideal for prototyping, testing plugins, and exploring ideas without any setup costs.
You can get as many of these disposable WordPress environments as you want, and each one includes a built-in PHP and WordPress version switcher to test your code across different configurations.
Embed it in your app, or take full control with the JavaScript client
The simplest way to integrate WordPress Playground into your own application is to embed it in an <iframe> and configure it using the query parameters API. The official showcase works this way: selecting thePendant theme and the Coblocks plugin updates the iframe's source to https://playground.wordpress.net/?theme=pendant&plugin=coblocks.
The iframe approach is quick to set up but only exposes basic configuration. For deeper control, the @wp-playground/client npm package provides a full API that lets you interact with the entire WordPress site—filesystem and PHP included. For more examples, check the interactive tutorial.
import {
connectPlayground,
login,
connectPlayground,
} from '@wp-playground/client';
const client = await connectPlayground(
document.getElementById('wp'), // An iframe
{ loadRemote: 'https://playground.wordpress.net/remote.html' },
);
await client.isReady();
// Login the user as admin and go to the post editor:
await login(client, 'admin', 'password');
await client.goTo('/wp-admin/post-new.php');
// Run arbitrary PHP code:
await client.run({ code: '<?php echo "Hi!"; ?>' });
// Install a plugin:
const plugin = await fetchZipFile();
await installPlugin(client, plugin);
WebAssembly PHP works standalone too
WordPress Playground isn't a single monolithic project. WebAssembly PHP is released independently and can be used separately. For browser-based projects, the @php-wasm/web npm package is optimized for a minimal bundle size; in Node.js, @php-wasm/node offers a broader set of PHP extensions. Adam used the former to add interactive PHP snippets to this WP_HTML_Tag_Processor tutorial:
import { PHP } from '@php-wasm/web';
const php = await PHP.load('8.0', {
requestHandler: {
documentRoot: '/www',
},
});
// Create and run a script directly
php.mkdirTree('/www');
php.writeFile('/www/index.php', `<?php echo "Hello " . $_POST['name']; ?>`);
php.run({ scriptPath: '/www/index.php' });
// Or use the familiar HTTP concepts:
const response = php.request({
method: 'POST',
relativeUrl: '/index.php',
data: { name: 'John' },
});
console.log(response.text); // Hello John
How it works: WebAssembly PHP, a SQL bridge, and an in-browser server
PHP wasn't designed to run in the browser. WordPress Playground compiles the PHP interpreter to WebAssembly using Emscripten, via a dedicated build pipeline. The vanilla PHP build itself is straightforward—only a few patches are needed, including adjusting a function signature and forcing a config variable. You can build it yourself with:
git clone https://github.com/WordPress/wordpress-playground
cd wordpress-playground && npm install
# Below, you can replace "8.2" with any other valid PHP version number.
npm run recompile:php:web:8.2
However, vanilla PHP builds aren't practical in a browser context. As server software, PHP has no JavaScript API to accept request bodies, upload files, or populate the php://stdin stream. WordPress Playground fills that gap with a dedicated PHP API module written in C plus a JavaScript PHP class exposing methods like writeFile() and run().
Since each PHP version is just a static .wasm file, the version switcher is deceptively simple: the browser downloads, for example, php_7_3.wasm instead of php_8_2.wasm.
A translation layer makes SQLite stand in for MySQL
WordPress normally requires MySQL, but no WebAssembly build of MySQL exists. WordPress Playground instead ships PHP with the native SQLite driver. The official SQLite Database Integration plugin intercepts MySQL queries and rewrites them in SQLite dialect. The 2.0 release includes a new translation layer that lets WordPress on SQLite pass 99% of the WordPress unit test suite.
The browser is the server
In a conventional WordPress setup, clicking a link initiates an HTTP request to a remote backend. WordPress Playground has no such backend. Instead, a Service Worker intercepts all outgoing requests and forwards them to an in-browser PHP instance running in a separate Web Worker.
Networking via WebSockets and Asyncify
WebAssembly programs are restricted to calling JavaScript APIs—a safety feature that complicates networking. PHP's low-level, synchronous networking code doesn't map naturally to JavaScript's high-level asynchronous APIs. WordPress Playground solves this with a WebSocket-to-TCP-socket proxy, Asyncify, and patches to deep PHP internals like php_select. It's complex but worthwhile: the Node.js-targeted PHP build can fetch web APIs, install composer packages, and even connect to a MySQL server.
Beyond the browser: Node.js and serverless
Because WordPress now runs on WebAssembly, the same setup works in a Node.js server—it shares the V8 engine. And with StackBlitz, Node.js itself runs in the browser, meaning you can run WordPress and PHP compiled to WebAssembly executing inside Node.js, also compiled to WebAssembly, in the browser. WebAssembly's growing presence in serverless computing could bring this architecture to that infrastructure as well.
A zero-setup, collaborative future for WordPress
The implications go beyond what's available today. A future WordPress workflow could start in a code editor with all setup completed, no local installation required. Sharing a link could enable multiplayer editing sessions similar to Google Docs, and a single click might deploy the finished work to any hosting provider.
Interactive tutorials, live plugin demos, staging sites, decentralized WordPress instances on edge servers—even building plugins from a phone—are all plausible follow-ons. The GitHub repository is open for contributions, discussion happens in the #meta-playground WordPress.org Slack channel, and you can reach Adam directly at [email protected].



