# WebAssembly

WebAssembly (Wasm) is a portable binary instruction format designed as a compilation target. You compile C, C++, Rust, Go, and other languages to a `.wasm` module, and any conforming runtime executes it — in a browser, on a server, or embedded inside another program. Two properties matter most: it's portable (the same module runs everywhere a runtime exists) and it's sandboxed (a module can only touch memory and functions the host explicitly hands it, so running untrusted Wasm inside your process is a defensible boundary rather than a foot-gun).

The behavior is pinned by the WebAssembly Core Specification, a W3C standard with a 1.0 and a 2.0 revision. Runtimes advertise which they implement, and there are official test suites a runtime is expected to pass. Extensions layer on top — the WebAssembly Exceptions proposal, for instance, gives native exception-handling instructions instead of unwinding by hand, which matters for C++ where exceptions are common. Runtimes and tools often require you to opt into such extensions explicitly ([[wazero]] and wasmtime both make you flag on exception support).

## Runtimes: interpreter vs compiler

A Wasm runtime executes a module one of two ways. An **interpreter** walks the bytecode directly — it runs on any platform the runtime itself compiles for and needs no per-architecture backend, but it's slower. An **ahead-of-time compiler** translates the module to native machine code when it's loaded, then runs that; typically an order of magnitude faster, but it needs a code generator for each CPU architecture, so it's limited to the ones the runtime supports (usually amd64 and arm64). [[wazero]], a pure-Go runtime, ships both and picks the compiler by default where it can.

## The wasm2js fallback

Not every environment can run Wasm — a browser may have it disabled. `wasm2js`, a tool from the binaryen project, recompiles a Wasm module back into JavaScript so it runs anywhere JS does. The output is slower than native Wasm but it finishes eventually, which is the point of a fallback. [[anubis-wasm-vendor-binary|Anubis]] uses exactly this: its proof-of-work check logic is written once in Wasm, shared by client and server so they stay in lockstep, and cross-compiled to JS via `wasm2js` for browsers with Wasm turned off. The idea traces to the talk *The Birth and Death of JavaScript*, which imagined a future where everything compiles to Wasm and JS becomes a compile target of last resort.

## Running untrusted code

The sandbox is why Wasm shows up in agent-tooling and plugin contexts: a host process can load a module and be sure it can't read arbitrary memory, open files, or make network calls unless the host wired those capabilities in. That makes it one option for [[sandboxing-ai-agents|sandboxing AI agents]] and other untrusted-code scenarios, alongside heavier isolation like microVMs and containers.

## Related

- [[wazero]] — zero-dependency pure-Go Wasm runtime
- [[anubis-wasm-vendor-binary]] — Wasm proof-of-work with a wasm2js fallback, and the reproducibility fight around vendoring wasm2js
- [[sandboxing-ai-agents]] — Wasm as one isolation layer among several
