Shubham Upadhyay

Senior Backend Architect

Open to Collaborate
Bengaluru, IN
Connect Channels
WebAssembly / PHP Runtime 6 min read Dec 2023 ShubhamLabs

Building a Browser-Based Coding Playground with PHP WebAssembly

Executing multi-file PHP, HTML, CSS, and JS entirely inside the client browser with WebAssembly for zero server footprint and unbreakable privacy.

Shubham Upadhyay

Shubham Upadhyay

Senior Backend & Systems Engineer

01.

The Problem: Executing Server-Side PHP in the Browser

One of the tools I wanted to build for ShubhamLabs was a browser-based coding playground where developers could write and experiment with HTML, CSS, JavaScript, and PHP in one place.

HTML, CSS, and JavaScript were relatively straightforward because the browser already provides an environment to work with them.

PHP was different. PHP is a server-side language and normally needs a PHP runtime to execute the code. The obvious implementation would have been to send the user's PHP code to my server, execute it there, and return the output to the browser.

For me, that immediately raised two concerns: Privacy and Security.

"Why execute the user's PHP on my server at all if I can execute it in their browser?"

— Shubham Upadhyay
02.

Why Server-Side Execution Was Rejected

Taking arbitrary PHP submitted by internet users and executing it on central infrastructure introduces massive security, privacy, and operational liabilities.

Privacy Concerns

  • A coding playground means users can paste anything into the editor — application code, database queries, API logic, or private project snippets.
  • If I send that code to my server for execution, I take responsibility for receiving and processing it.
  • Even if I do not intentionally store the code, it still has to reach and transit my infrastructure.
  • Handling confidential user source code creates an unnecessary ethical and legal responsibility that I wanted to avoid.

Security & Infrastructure Hazards

  • PHP interacts with the host environment: requires isolation around filesystem, network sockets, child processes, CPU, and memory.
  • Complex container sandboxing needed to prevent intentional infinite loops, malicious exploits, and resource exhaustion.
  • Building and securing a server-side sandbox turns a simple developer tool into a heavy infrastructure project.
  • More servers mean more deployment pipelines, 24/7 monitoring, security patches, and escalating monthly cloud costs.
03.

The Approach: Bringing the PHP Runtime to the Browser

The solution was WebAssembly.

Instead of trying to execute PHP using the PHP installation on my server, I use a PHP runtime that has been compiled to WebAssembly and load that runtime into the browser.

The important part is that the PHP runtime itself is running inside the browser. The user's PHP source is therefore processed locally rather than being uploaded to a PHP execution server.

User Browser
(Interactive Code Editor)
←––→
JS Bridge
(Runtime Event Router)
–––→
PHP WASM
(Compiled Runtime)
Virtual VFS
(In-Memory Filesystem)
Console Output
(DOM Terminal Buffer)
–––→
Target Databases & APIs
Zero Egress
(100% Private)
Dynamic Load
(Lazy Fetched)
Preview iframe
(HTML/CSS/JS Sandbox)
04.

How PHP WebAssembly Works

WebAssembly gives the browser a way to execute compiled code at near-native speeds inside a controlled runtime environment.

In this case, I am not converting PHP into JavaScript. Instead, the PHP runtime itself is compiled to WebAssembly. When the playground needs PHP execution, the WebAssembly module is loaded into the browser memory. JavaScript acts as the bridge between the playground interface and the WebAssembly runtime.

The browser is no longer just the editor — it becomes the environment in which PHP is actually executed.

CLIENT-SIDE EXECUTION LIFECYCLE
1 User writes PHP
2 JS receives source
3 Provided to WASM runtime
4 PHP runtime parses & executes
5 Output & errors captured
6 Console displays result
05.

Dynamic Runtime Loading

One issue with WebAssembly is bundle weight. The runtime itself is not something I want to load unnecessarily when a user only wants to work with HTML, CSS, or JavaScript.

So I kept the PHP execution environment separate from the initial application experience.

The PHP runtime is loaded dynamically when PHP execution is required. That means the playground can start without immediately loading everything required for PHP execution, and the heavier runtime is introduced when the user actually needs it.

This was essential for keeping the general playground experience fast, responsive, and lightweight on both desktop and mobile.

06.

Supporting Multiple PHP Files via Virtual Filesystem

A real PHP project is rarely a single file. I therefore wanted the playground to support a project structure rather than only executing one isolated PHP snippet.

For example: index.php and helper.php, where index.php can use functions or classes from helper.php.

The WebAssembly environment provides an in-memory virtual filesystem (VFS) for the PHP runtime. The playground places the project files into that virtual environment before execution.

So when PHP executes require 'helper.php', the PHP runtime can resolve that file inside its virtual environment. This makes the playground much closer to working with a small real-world PHP project rather than a toy snippet executor.

source-code
In-Memory Engine
// Virtual Filesystem (VFS) Project Tree
project/
├── index.php    // require 'helper.php'; echo formatUser($user);
└── helper.php   // function formatUser($user) { return htmlspecialchars($user); }
07.

Orchestrating HTML, CSS, JavaScript, and PHP

PHP was the difficult part, but the playground also needed to coordinate frontend web technologies. The playground uses dedicated execution paths depending on the language:

Frontend Web Stack (HTML / CSS / JS)

  • HTML and CSS are rendered directly in the browser DOM.
  • JavaScript executes inside an isolated, sandboxed preview iframe.
  • Sandboxing prevents user scripts from accessing the host application context.
  • Instant live updates provide immediate visual feedback as code is written.

Backend Stack (PHP via WASM)

  • PHP source is passed into the WebAssembly runtime via JavaScript bridge.
  • Standard output (echo, print, dump) is piped to the interactive console.
  • Execution errors and stack traces are captured and formatted.
  • Unified environment where frontend preview and backend console coexist.
08.

Security: Why Client-Side Execution Made More Sense

Moving PHP execution to the browser does not mean that WebAssembly magically makes arbitrary code safe. The important benefit is different: I no longer need to take arbitrary PHP source code and execute it on my own server.

That removes an entire class of server-side concerns from the architecture.

If I had chosen server-side execution, I would have had to maintain a strong isolation boundary around every execution request and continuously think about what the submitted PHP could access.

With client-side execution, the user's code remains inside the browser's execution environment. The browser already provides an important security boundary between web applications and the user's operating system, and WebAssembly execution takes place within that browser environment.

This does not remove every possible security concern, but it significantly reduces what I need to expose and protect on my own infrastructure.

09.

Cost and Operational Simplicity

This decision was also practical. ShubhamLabs is not backed by a large engineering or infrastructure team. I build and maintain it myself.

Server-Side Sandbox Burden (Avoided)

  • Operating dedicated infrastructure specifically for running untrusted PHP code.
  • Additional compute clusters, load balancers, and persistent container workers.
  • Continuous security monitoring, OS patches, and abuse mitigation.
  • Escalating monthly cloud compute bills during traffic surges.

WebAssembly Client Model (Achieved)

  • My server mainly needs to deliver the web application and static assets.
  • Actual PHP execution happens on the user's machine through their browser.
  • $0 monthly cloud compute execution bills for arbitrary code evaluation.
  • Architecture is substantially simpler, resilient, and effortless to operate.
10.

Trade-offs & Practical Scope

Running a PHP runtime through WebAssembly has limitations compared with running PHP on a dedicated Linux server. There are differences in:

So this is not intended to replace a real PHP development or production environment. The purpose is different: a convenient, zero-friction environment for learning, experimenting, testing examples, and quickly trying PHP code without setting up a PHP server.

  • Available PHP extensions (C extensions requiring OS shared libraries are not bundled)
  • Operating-system access and low-level system call boundaries
  • Network behavior (outbound raw TCP sockets cannot be opened directly from browser WASM)
  • Filesystem behavior (in-memory virtual filesystem resets on page reload unless exported)
  • Browser resource limits and tab thread constraints for heavy jobs
  • Initial runtime loading bandwidth on slower connections
11.

Key Results & Architectural Takeaway

Client-Side PHP Execution

Executed multi-file PHP scripts directly inside the browser with zero server roundtrips.

Unbreakable User Privacy

User code stays completely local; proprietary snippets and test queries never leave the machine.

Zero Infrastructure Burden

Eliminated dedicated Docker sandbox servers, keeping ongoing maintenance and cloud compute bills at $0.

Questioning Architecture Early

A different architectural decision can sometimes remove a problem altogether instead of requiring a more complicated solution to manage it.

Explore Further

Want to review the full ShubhamLabs overview?

Check out technical architecture, problems faced, and complete tech stack.

View Project Overview
Chat on WhatsApp
Navigating...