Agent skill

Compile Php Wasm

by WordPress in WordPress/wordpress-playground

Compile PHP.wasm main modules and side modules (dynamic extensions) for Node.js and web platforms.

GPL-2.0Auto-check passedDevOps & Cloud

Install Compile Php Wasm

skills CLI
$ npx skills add WordPress/wordpress-playground --skill compile-php-wasm -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install WordPress/wordpress-playground compile-php-wasm --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/WordPress/wordpress-playground.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/compile-php-wasm .claude/skills/compile-php-wasm && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
compile-php-wasm
GitHub stars
2k
Token cost
~2.8k tokens
SKILL.md length
584 words
Files
1
Skills in repo
5
Repo updated
First seen
Licence
GPL-2.0

At a glance

Compile PHP.wasm main modules and side modules (dynamic extensions) for Node.js and web platforms.

  • Works in 4 steps: Removed/renamed APIs → Stricter Clang compiler → JSPI behavioral changes → …
  • Recompiling PHP
  • SKILL.md covers Quick Reference, Side Module Compilation, Cache Busting and WASM Binary Inspection, plus 1 more section
  • Calls npx, node and npm

What it does

Compile Php Wasm is an agent skill from WordPress/wordpress-playground. Compile PHP.wasm main modules and side modules (dynamic extensions) for Node.js and web platforms. Use when recompiling PHP, adding Emscripten flags, modifying Dockerfiles, building extensions as SIDEMODULE, upgrading Emscripten, or troubleshooting compilation failures.

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in DevOps & Cloud, covering Containers. It works with WebAssembly, PHP, WordPress and Node.js. The repository describes itself as: Run WordPress in the browser via WebAssembly PHP. The licence is GPL-2.0.

When your agent uses it

  • Recompiling PHP
  • Adding Emscripten flags
  • Modifying Dockerfiles
  • Building extensions as SIDEMODULE

Example prompts

  • “/compile-php-wasm”

Requirements

  • Node.js
  • Docker

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Removed/renamed APIs
  2. Stricter Clang compiler
  3. JSPI behavioral changes
  4. Debugging approach

What it can do on your machine

Read from SKILL.md and the folder at commit 4d39322. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx
    • node
    • npm
    • docker

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, npm and docker, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Compile Php Wasm loads about 2.8k tokens when it runs. Until then it costs about 72 tokens; SKILL.md has 584 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~72
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from WordPress/wordpress-playground at commit 4d39322, republished under its GPL-2.0 licence (© WordPress). 584 words, ~2,840 tokens.

Download SKILL.mdSave it as .claude/skills/compile-php-wasm/SKILL.md (or your agent's skills folder).
name
compile-php-wasm
description
Compile PHP.wasm main modules and side modules (dynamic extensions) for Node.js and web platforms. Use when recompiling PHP, adding Emscripten flags, modifying Dockerfiles, building extensions as SIDE_MODULE, upgrading Emscripten, or troubleshooting compilation failures.

Compiling PHP.wasm

Patterns for compiling PHP.wasm main modules and dynamic extension side modules in the WordPress Playground repository.

Requires: Docker, Node.js (version from .nvmrc), npm

Quick Reference

bash
```bash
# Recompile a specific version for ALL platforms and modes (web+node, jspi+asyncify)
npx nx recompile-php:all php-wasm-web -- --PHP_VERSION=8.5
npx nx recompile-php:all php-wasm-node -- --PHP_VERSION=8.5

# Recompile a specific version + platform + single mode
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.5
npx nx recompile-php:asyncify php-wasm-web -- --PHP_VERSION=8.5
npx nx recompile-php:jspi php-wasm-node -- --PHP_VERSION=8.5
npx nx recompile-php:asyncify php-wasm-node -- --PHP_VERSION=8.5

# Recompile all PHP versions for a platform
npm run recompile:php:web
npm run recompile:php:node

# Debug build (DWARF info)
# Use when you need to step through WASM in a debugger (Chrome DevTools DWARF
# support) or need better stack traces with C function names. Helpful for
# crashes like `RuntimeError: unreachable` where you need to identify which
# C function is involved. Produces much larger binaries.
npx nx recompile-php:all php-wasm-web -- --WITH_DEBUG=yes
npx nx recompile-php:all php-wasm-node -- --WITH_DEBUG=yes

# Source maps
# Use when you want to map JS glue code back to its Emscripten-generated
# source locations. Lighter weight than DWARF but only covers the JS side,
# not the WASM internals.
npx nx recompile-php:all php-wasm-web -- --WITH_SOURCEMAPS=yes
npx nx recompile-php:all php-wasm-node -- --WITH_SOURCEMAPS=yes

# Reset caches before rebuilding
node node_modules/.bin/nx reset
docker rmi php-wasm:latest

## Build Pipeline Overview

The build system lives in `packages/php-wasm/compile/`. The pipeline is:

Dockerfile (Emscripten + PHP source + patches) ↓ docker build .wasm binary + .js glue file ↓ post-link Dockerfile patches (replace.sh) Patched .js glue file ↓ NX executor copies to dist/ Final artifacts in package dist/


Key files:

| File | Purpose |
|------|---------|
| `Dockerfile` | Main build — downloads PHP source, applies patches, runs `emcc` |
| `Makefile` | Orchestrates Docker builds per PHP version |
| `build.js` | Node script invoked by NX executors |
| `.emcc-php-wasm-flags` | Emscripten linker flags (generated during build) |
| `.emcc-php-wasm-sources` | Source/library paths for linking (generated during build) |
| `replace.sh` / Dockerfile `RUN sed` | Post-link patches to the compiled JS glue file |

## Main Module Compilation

### Emscripten flags that matter

| Flag | Purpose |
|------|---------|
| `ASYNCIFY` | Enables Asyncify (unwind/rewind for async JS calls) |
| `ASYNCIFY_ONLY=[func1,func2,...]` | Whitelist of functions Asyncify instruments (critical for binary size) |
| `JSPI` | Enables JSPI (V8 native stack switching, replaces Asyncify) |
| `JSPI_IMPORTS=[func1,...]` | JS imports wrapped with `WebAssembly.Suspending` |
| `JSPI_EXPORTS=[func1,...]` | WASM exports wrapped with `WebAssembly.promising` |
| `MAIN_MODULE=1` | Enables `dlopen` — exports all symbols for dynamic linking |
| `MAIN_MODULE=2` | Like `=1` but only exports explicitly listed symbols |
| `EXPORTED_FUNCTIONS=[...]` | C functions accessible from JS |
| `EXPORTED_RUNTIME_METHODS=[...]` | Emscripten runtime helpers accessible from JS |
| `ENVIRONMENT=web,worker` | Target environments (affects code generation) |
| `INITIAL_MEMORY=256MB` | Starting linear memory size |

### MAIN_MODULE for dynamic extensions

When adding `dlopen` support (`MAIN_MODULE=1`):

- **Never use `-l` flags for C libraries.** Library directories contain both
  `.a` (static) and `.so` (WASM side module) files. With `MAIN_MODULE`, PIC
  mode makes the linker prefer `.so`. When `wasm-ld` encounters a `.so`
  under `--whole-archive`, it crashes with SIGSEGV. Fix: use explicit `.a`
  paths in `.emcc-php-wasm-sources` instead of `-l` flags.

- **`MAIN_MODULE=1` has linker limitations.** `wasm-ld` cannot handle
  `--whole-archive` + `--experimental-pic` on archives as large as
  `libphp.a`. This is a fundamental limitation. Start with `=1` (exports
  all symbols), then consider `=2` for optimization.

- **ENVIRONMENT=web,worker changes code generation.** With a single
  environment, Emscripten hardcodes booleans (`ENVIRONMENT_IS_WEB = true`).
  With multiple, it generates runtime detection. Post-processing regex
  patterns in the Dockerfile must handle both forms.

### Post-link Dockerfile patches

The Dockerfile uses `sed` / `replace.sh` to modify the compiled JS glue
file after Emscripten runs. Common patches:

- **Inject `_malloc` binding** when it's not auto-exposed:
  ```js
  PHPLoader['malloc'] = wasmExports['malloc'];
  // Injected right after assignWasmExports() in the glue file
  • Cache Asyncify buffers to prevent memory.grow() corruption during handleSleep() (see debug-php-wasm-main-module skill for details)
  • Guard ENVIRONMENT_IS_* substitution for multi-environment builds
Emscripten version upgrade checklist

When upgrading Emscripten, expect these categories of breakage:

  1. Removed/renamed APIs:

    • setErrNo() removed — use HEAP32[___errno_location() >> 2] = code
    • _malloc/_free no longer auto-exposed — add to EXPORTED_FUNCTIONS
    • HEAPU8/HEAPU32 need explicit EXPORTED_RUNTIME_METHODS
  2. Stricter Clang compiler:

    • -Wincompatible-pointer-types becomes an error. Fix: correct the types, not the warning level.
    • PHP version checks like #if PHP_MAJOR_VERSION >= 8 may be too broad (e.g. zend_file_handle.filename is const char * in 8.0 but zend_string * in 8.1+)
  3. JSPI behavioral changes:

    • WASI syscall wrappers (e.g. fd_close) may gain JS intermediate frames, breaking JSPI suspension. Symptom: startup hangs silently. Fix: remove from JSPI_IMPORTS/JSPI_EXPORTS.
    • exitRuntime() → __funcs_on_exit() may trigger JSPI suspension. Add to JSPI_EXPORTS and EXPORTED_FUNCTIONS.
  4. Debugging approach:

    • Build PHP 8.4 first (fewest compatibility issues)
    • Fix build errors, then run JSPI tests
    • Once 8.4 passes, test 8.0 and 7.4 for version-specific issues
    • Patch PHP source files (php*.patch) for older versions as needed

Side Module Compilation

Side modules are PHP extensions (Xdebug, intl, GD, etc.) compiled as WASM shared libraries loaded via dlopen.

Build requirements

The extension build needs a minimal PHP installation (for phpize and headers). Key Emscripten-specific requirements:

RequirementDetail
Inline assembly patchesHAVE_ASM_GOTO, ZEND_USE_ASM_ARITHMETIC, __GNUC__, __clang__ — same patches as main Dockerfile
--without-pcre-jitSLJIT uses x86 assembly, unavailable in WASM
PHP 8.4 flag change--disable-libxml became --without-libxml
Remove -lm from MakefileMath library is in the main module
EMCC_FLAGS-sSIDE_MODULE -D__x86_64__ -sWASM_BIGINT
wasm-opt path/root/emsdk/upstream/bin/wasm-opt (not on PATH)
Asyncify side modules

When the side module uses custom renamed imports (e.g. -Drecv=wasm_recv), you MUST pass -sASYNCIFY_IMPORTS=<custom_name>:

dockerfile
export EMCC_FLAGS="-sSIDE_MODULE -sASYNCIFY -sASYNCIFY_IMPORTS=wasm_recv"

Without this, Binaryen won't instrument call sites for those imports — locals won't be saved/restored, causing table index is out of bounds during Asyncify rewind.

Show full SKILL.md (236 more words)Show less
Libtool issues

Libtool refuses to create WASM shared libraries. Two workarounds:

  1. Patch libtool's archive_cmds — replace $CC with emcc $EMCC_FLAGS -shared --whole-archive <static archives> --no-whole-archive
  2. Bypass libtool entirely — manually link with em++, discovering all .o files recursively (find . -path '*/.libs/*.o')

When using approach 2, check subdirectories — C++ libraries often produce .o files in nested paths that build scripts miss.

Pre-compiled artifacts

ICU .a archives and other pre-built artifacts committed to the repo may not match current build flags. When MAIN_MODULE=1 requires PIC, pre-built non-PIC archives cause R_WASM_MEMORY_ADDR_SLEB relocation errors. Rebuild from source if flags changed.

Cache Busting

Docker BuildKit caches aggressively. Before rebuilding:

bash
# Remove the image to force a true rebuild
docker rmi php-wasm:latest

# docker builder prune alone is NOT sufficient — BuildKit reuses
# intermediate layers from existing images

# Also reset NX cache
node node_modules/.bin/nx reset

WASM Binary Inspection

When the build produces .wasm files that don't work correctly:

bash
# List exports and imports
wasm-objdump -x module.wasm

# Disassemble
wasm-objdump -d module.wasm

# Print WAT form (verify Asyncify instrumentation)
wasm-opt --print module.so

# From JavaScript — inspect a side module
node -e "
  const fs = require('fs');
  const mod = new WebAssembly.Module(fs.readFileSync('module.so'));
  console.log('exports:', WebAssembly.Module.exports(mod).map(e => e.name));
  console.log('imports:', WebAssembly.Module.imports(mod).map(i => i.name));
"

Cross-reference symbol lists with:

  • The ASYNCIFY_ONLY function list (main module)
  • EXPORTED_FUNCTIONS in the Emscripten build flags
  • SIDE_MODULE / MAIN_MODULE dynamic linking expectations

Diagnostic Cheat Sheet

SituationAction
Build fails with compiler errorRead the error, fix C/Makefile, retry
Build succeeds but WASM won't loadList imports — runtime is missing something
Build succeeds but runtime crashesList exports + check Asyncify/JSPI function lists
Behavior is wrong but no errorAdd printf to C code, rebuild, trace
Extension fails as SIDE_MODULECheck dynamic linking flags, verify symbol visibility
Linker SIGSEGV with MAIN_MODULESwitch -l flags to explicit .a paths
R_WASM_MEMORY_ADDR_SLEB errorPre-built archive not compiled with PIC — rebuild from source
Don't know what a build step doesRead the Dockerfile/Makefile line by line

© WordPress, GPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/compile-php-wasm of WordPress/wordpress-playground.

Open the folder on GitHubat commit 4d39322

Compare with similar skills

Compile Php Wasm next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Compile Php Wasm compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Compile Php Wasm this skillWordPress/wordpress-playground2k—~2.8kAutomated safety check: PassGPL-2.0
Reflexo ReleaseMyriad-Dreamin/typst.ts1.2k—~1.5kAutomated safety check: PassApache-2.0
Wp EnvWordPress/agent-skills2.2k—~2.2kAutomated safety check: PassCustom licence
GitHub Actions CreatorFNOSP/FlyNarwhal4951 repos~2.4kAutomated safety check: PassAGPL-3.0
Ddevhaxtheweb/haxcms-php130—~1.6kAutomated safety check: PassApache-2.0
Releasear-io/ar-io-node127—~4.2kAutomated safety check: NotesAGPL-3.0

Similar skills

  • Reflexo Release

    Myriad-Dreamin/typst.ts

    Guide Reflexo/typst.ts release preparation and operator handoffs.

    1.2k GitHub stars~1.5k tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Wp Env

    WordPress/agent-skills

    A skill your agent uses when setting up, configuring, or troubleshooting local WordPress development environments with @wordpress/env (wp-env).

    2.2k GitHub stars~2.2k tokensUpdated 3 days ago
    DevOps & CloudAuto-check passed
  • GitHub Actions Creator

    FNOSP/FlyNarwhal

    A skill your agent uses when the user wants to create, generate, or set up a GitHub Actions workflow.

    495 GitHub starsUsed in 1 repo~2.4k tokens
    DevOps & CloudAuto-check passed
  • Ddev

    haxtheweb/haxcms-php

    DDEV local development environment guidance for Docker-based PHP/Node projects.

    130 GitHub stars~1.6k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Release

    ar-io/ar-io-node

    Drive the AR.IO Node release process end-to-end — preflight checks, prepare commit, finalize with image SHAs, test docker compose profiles, tag & publish, and post-release cleanup.

    127 GitHub stars~4.2k tokensUpdated today
    DevOps & CloudAuto-check: notes
  • Shopware CLI Docker

    shopware/shopware-cli

    A skill your agent uses when working on Docker-backed Shopware projects and needing to run Shopware or Symfony CLI commands, interact with project services or databases, start or stop the…

    123 GitHub stars~1.8k tokensUpdated yesterday
    DevOps & CloudAuto-check passed

More from WordPress/wordpress-playground

  • Doc Screenshots

    WordPress/wordpress-playground

    Annotate UI screenshots with documentation callouts in Fellyph's established visual style — uniform-width orange arrows with white halos, double-stroke target outlines, numbered callout cards, dim…

    2k GitHub stars~1.8k tokensUpdated yesterday
    Auto-check passed
  • Debug Php Wasm Main Module

    WordPress/wordpress-playground

    Debug PHP.wasm main module crashes including Asyncify errors (unreachable, memory access out of bounds), JSPI errors (SuspendError, trying to suspend JS frames), WASM memory growth bugs, and runtime…

    2k GitHub stars~3.1k tokensUpdated yesterday
    Auto-check passed
  • Debug Php Wasm Side Modules

    WordPress/wordpress-playground

    Debug WASM side modules (dynamic PHP extensions) including dlopen failures, SIDEMODULE loading, JSPI suspension crashes in extensions, C++ weak symbol issues, and extension runtime errors.

    2k GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Playground Website Debugging

    WordPress/wordpress-playground

    Debug the WordPress Playground website by running the dev server from source and interacting with it via Playwright MCP.

    2k GitHub stars~1.9k tokensUpdated yesterday
    Auto-check passed

Categories

Questions about Compile Php Wasm

What does Compile Php Wasm do?

Compile PHP.wasm main modules and side modules (dynamic extensions) for Node.js and web platforms. Compile Php Wasm is an agent skill from WordPress/wordpress-playground.js and web platforms.

When should I use Compile Php Wasm?

Compile Php Wasm fits situations like: recompiling PHP; adding Emscripten flags; modifying Dockerfiles; building extensions as SIDEMODULE.

How do I install Compile Php Wasm in Claude Code?

Run `npx skills add WordPress/wordpress-playground --skill compile-php-wasm -a claude-code`. Or copy the skill folder (.agents/skills/compile-php-wasm in WordPress/wordpress-playground) into .claude/skills/compile-php-wasm in your project. Claude Code loads it when a task matches its description.

How do I install Compile Php Wasm in Codex?

Run `npx skills add WordPress/wordpress-playground --skill compile-php-wasm -a codex`. Or copy the skill folder (.agents/skills/compile-php-wasm in WordPress/wordpress-playground) into .agents/skills/compile-php-wasm in your project. Codex loads it when a task matches its description.

Can I use Compile Php Wasm in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add WordPress/wordpress-playground --skill compile-php-wasm -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/compile-php-wasm, .gemini/skills/compile-php-wasm, .github/skills/compile-php-wasm and .opencode/skills/compile-php-wasm in your project.

What does Compile Php Wasm need to run?

Going by SKILL.md and its folder, Compile Php Wasm needs the command-line tools its instructions call (npx, node, npm and docker). Our summary lists: Node.js; Docker.

Does Compile Php Wasm access the network?

SKILL.md contains no URLs. Its commands use npx, npm and docker, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Compile Php Wasm safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Compile Php Wasm use?

Compile Php Wasm is published under the GPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Compile Php Wasm use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Compile Php Wasm?

Skills that share tags, products or a category with Compile Php Wasm: Reflexo Release (Myriad-Dreamin/typst.ts, 1.2k stars), Wp Env (WordPress/agent-skills, 2.2k stars), GitHub Actions Creator (FNOSP/FlyNarwhal, 495 stars) and Ddev (haxtheweb/haxcms-php, 130 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Compile Php Wasm?

WordPress (a GitHub organization) maintains it in WordPress/wordpress-playground, which has 1,973 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 7, 2026.

Source: WordPress/wordpress-playground on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.