· 3 min read
The runtime surplus
WebAssembly has an engine surplus because runtimes can compete independently while useful contracts, packages, debugging, and deployment require ecosystem agreement.

You wanted a safe plugin system. The ecosystem asked whether you prefer Cranelift, LLVM, an interpreter, ahead-of-time compilation, just-in-time compilation, pure Go, pure Java, Rust, C++, edge, embedded, or universal.
People joke that WebAssembly has more runtimes than users. It isn't literally true — browsers run enormous amounts of Wasm without asking anyone to install Wasmtime — but outside the browser the joke lands, because picking an engine has somehow become the first step of every tutorial.
“I need a safe plugin system.”
- Wasmtime
- Wasmer
- WasmEdge
- WAMR
- wazero
- wasmi
- Chicory
- GraalWasm
Engines are the easy hard part#
A community-maintained catalogue of WebAssembly runtimes needs a contents page with more than thirty names, including projects already marked unmaintained. I lost most of an evening to that list once, comparing engines for a plugin I never got around to writing. The layer is attractive to build: one team can own parsing, validation, compilation, sandboxing, and host calls without asking anyone's permission, then publish a benchmark.
Many of the differences are legitimate. wazero stays pure Go so it never touches CGO, Chicory exists because some teams need everything on the JVM, and the WebAssembly Micro Runtime squeezes into embedded devices and edge boxes. Those projects answer host constraints — where the runtime has to live — rather than fighting over the same user.
Here is the asymmetry, I think. A runtime team can compete on its own schedule, but stable interfaces, package conventions, debugger behavior, and portable host guarantees all require agreement, and agreement is slow. So the ecosystem produces engines faster than it produces the boring shared layer that would make the engines interchangeable.
The contract is the product#
This is closer to what you actually wanted:
package example:thumbnail@1.0.0;world thumbnailer { export resize: func( image: list<u8>, width: u32, ) -> result<list<u8>, string>;}The WebAssembly Interface Type language describes the contract and nothing else: the component says what it exports and what it needs, and the host decides how that contract gets run. Your plugin shouldn't care whether the engine beneath it was written in Rust, Go, Java, or regret.
WASI is the same move applied to the environment. WASI 0.3 shipped on June 11, 2026 with native asynchronous functions, streams, and futures, and its roadmap currently lists support in Wasmtime 43 and later plus the JavaScript component tooling in jco. A month in, that is the list. The useful common surface matures more slowly than the engines beneath it — as far as I can tell, it always has.
What you actually care about, as a plugin author, is whether files, clocks, streams, and errors mean the same thing everywhere, and whether the module can be tested, signed, debugged, and upgraded. Which code generator lowered your i32.add is the host operator's problem.
Hide the engine#
If you own a host, the constraints you already have will mostly pick the runtime for you — a Go binary wants wazero, a JVM application wants Chicory, a microcontroller wants WAMR, a component platform probably wants Wasmtime. Then stop advertising the choice. Publish the capabilities, the resource limits, the upgrade policy, the contract your users can rely on.
If you publish a component, publish its WIT world and what it is compatible with. If you write a tutorial, start with the useful plugin and leave the runtime matrix out — a reader who has to become a runtime historian before calling resize has already lost the portability the whole stack was promising.
The browser people quietly solved this years ago. Chrome, Firefox, and Safari run Wasm through entirely different engines, and nobody opening a tab knows or cares which one they got. I would like the server side to feel like that. The last plugin tutorial I read spent its first three paragraphs comparing engines, and the resize function — the part I came for — sat below the fold.