Title: Running PHP apps in the browser with ServiceWorkers and Worker Threads
Published: July 15, 2026
Last modified: July 16, 2026

---

# Running PHP apps in the browser with ServiceWorkers and Worker Threads

[ Back to top](https://developer.wordpress.org/playground/developers/architecture/browser-concepts/?output_format=md#wp--skip-link--target)

On a high level, WordPress Playground works in web browsers as follows:

 * The `index.html` file on playground.wordpress.net loads the `remote.html` file
   via an `<iframe src="/remote.html">`.
 * `remote.html` starts a Worker Thread and a ServiceWorker and sends back the download
   progress information.
 * The Worker Thread starts PHP and populates the filesystem with a WordPress patched
   to run on SQLite.
 * The ServiceWorker starts intercepting all HTTP requests and forwarding them to
   the Worker Thread.
 * `remote.html` creates an `<iframe src="/index.php">`, and the Service Worker 
   forwards the `index.php` request to the Worker Thread where the WordPress homepage
   is rendered.

Visually, it looks like this:

![Architecture overview](https://i0.wp.com/raw.githubusercontent.com/WordPress/wordpress-
playground/refs/heads/trunk/packages/docs/site/static/img/architecture-overview.
webp?ssl=1)

## High-level ideas

The [`@php-wasm/web`](https://github.com/WordPress/wordpress-playground/blob/trunk/packages/php-wasm/web/)
is built on top of the following ideas:

 * [**Browser tab orchestrates everything**](https://developer.wordpress.org/playground/developers/architecture/browser-tab-orchestrates-execution)–
   The browser tab is the main program. Closing or reloading it means destroying
   the entire execution environment.
 * [**Iframe-based rendering**](https://developer.wordpress.org/playground/developers/architecture/browser-iframe-rendering)–
   Every response produced by the PHP server must be rendered in an iframe to avoid
   reloading the browser tab when the user clicks on a link.
 * [**PHP Worker Thread**](https://developer.wordpress.org/playground/developers/architecture/browser-php-worker-threads)–
   The PHP server is slow and must run in a web worker, otherwise handling requests
   freezes the website UI.
 * [**Service Worker routing**](https://developer.wordpress.org/playground/developers/architecture/browser-service-workers)–
   All HTTP requests originating in that iframe must be intercepted by a Service
   worker and passed on to the PHP worker thread for rendering.

First published

July 15, 2026

Last updated

July 16, 2026

Edit article

[ Improve it on GitHub: Running PHP apps in the browser with ServiceWorkers and Worker Threads ](https://raw.githubusercontent.com/WordPress/wordpress-playground/trunk/packages/docs/site/docs/developers/23-architecture/08-browser-concepts.md)

Changelog

[ See list of changes: Running PHP apps in the browser with ServiceWorkers and Worker Threads ](https://developer.wordpress.org/playground/developers/architecture/browser-concepts/?output_format=md#)

[  Previous: Asyncify and JSPI: Stack Switching in PHP WebAssembly](https://developer.wordpress.org/playground/developers/architecture/wasm-asyncify/)

[  Next: Browser tab orchestrates the execution](https://developer.wordpress.org/playground/developers/architecture/browser-tab-orchestrates-execution/)