A collection of hands-on experiments exploring WebAssembly (WASM) as an alternative to traditional container runtimes. Each experiment tests a concrete hypothesis, measures real numbers, and documents what held up and what didn't.
The premise: WASM runtimes can replace Docker containers for serverless-style workloads — smaller artifacts, faster cold starts, lower memory. These experiments validate (or refute) that claim with reproducible benchmarks on real hardware.
Reference: AWS's Stealth Container Killer
| # | Name | Status | What it tests |
|---|---|---|---|
| 001 | hello_world | results pending | Flask/Docker vs Pyodide/Chromium vs Wasmtime — cold start, memory, throughput |
| 002 | chromium_sandbox | done | Chromium+Pyodide isolation strategies — worker pools, BrowserContext pooling, JS↔WASM bridge overhead |
| 003 | wasm_compile | results pending | Compiling JS/Python/Rust to .wasm via Spin/componentize-py/cargo, native vs. podman |
| 004 | static_wasi_hello | done | Static HTML page, zero server at execution time — mvl-lang/mvl-playground's actual architecture |
| 005 | stdout_capture_load | done | stdout/stderr capture correctness + overhead at 10/1,000/100,000 lines |
| 006 | worker_kill_switch | done | Worker.terminate() against a genuine infinite loop — is it actually instant? (No — ~2.1s) |
| 007 | custom_runtime_vs_interpreter | done | Hand-written 78-line JS runtime shim vs. componentize-py vs. Pyodide — artifact size, cold start, build complexity |
| 008 | mvl_example_wasm_harness | done | Standalone (non-browser) host for mvl build --backend=wasm output — found and fixed 3 real memory/tag bugs in the ported runtime, one of which was mislabeled as a compiler bug (mvl-lang/mvl#2083, corrected and closed) |
| 009 | rust_native_host | done | Native Rust host embedding wasmtime directly, no HTTP — checks a Medium article's "200µs" claim against true cold start and against its own methodology |
| 010 | mastermind_web | done | Mastermind scored entirely by a compiled .wasm module, click-driven UI — reverse-engineered the struct-return ABI, worked around a dead-code-elimination bug dropping string data for unreached pub functions |
| 011 | mastermind_cli_wasi | done | Same game, pure Rust, wasm32-wasip1, real WASI fd_read stdin — proves genuine interactive I/O works under WASM/WASI, isolating that MVL's --backend=wasm gap is backend-specific, not a WASM/WASI limitation |
experiments/
└── NNN_name/ # Self-contained experiment
├── README.md # Hypotheses, methodology, results
├── benchmark.sh # Reproducible benchmark runner
└── leg*/ # One directory per runtime under test
install.sh # Check and install prerequisites
Run ./install.sh to verify your environment. It checks all required tools and
auto-installs the Rust WASM target if rustup is present.
| Tool | Purpose | Install |
|---|---|---|
| podman (preferred) or docker | Container runtime for Leg 1 | brew install podman |
| wasmtime | Native WASM runtime for Leg 3 | brew install wasmtime |
| rustup + wasm32-wasip2 | Compile Rust to WASM component | brew install rustup && rustup-init |
| node / npm | Puppeteer harness for Leg 2 | brew install node |
| hey | Warm benchmark (1000 req) | brew install hey |
Experiments use Podman (rootless, daemonless) by default. Docker works as a
drop-in if Podman is not available — install.sh detects whichever is running and
sets CONTAINER_CMD accordingly. Leg 1's run.sh respects this variable.
To start Podman on macOS:
brew install podman
podman machine init
podman machine startSee CONTRIBUTING.md.
Please report vulnerabilities privately, not as a GitHub issue. See SECURITY.md.
Copyright 2026 Schuberg Philis B.V.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License in LICENSE or at https://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.