WebAssembly
WebAssembly (abbreviated Wasm) is a binary instruction format originally designed as a compilation target for running C, C++, and Rust code in web browsers at near-native speed. It was standardized by the W3C (World Wide Web Consortium) in 2019. Since then, Wasm has expanded well beyond browsers into server-side, edge, and embedded use cases.
Why Wasm matters outside the browser
The properties that make Wasm useful in browsers — portable bytecode, sandboxed execution, near-native performance — turn out to be valuable anywhere you need to run untrusted or third-party code safely:
- Plugin systems: Helm 4, Envoy proxy, OPA (Open Policy Agent), Zellij (terminal multiplexer), Figma
- Edge computing: Cloudflare Workers, Fastly Compute, Fermyon Spin
- Embedded runtimes: running user-supplied logic inside databases, message brokers, or CLI tools
The sandbox model
A Wasm module executes inside a linear memory sandbox:
- It gets a contiguous block of memory (measured in 64 KiB pages) and cannot access anything outside it.
- It has no ambient capabilities: no filesystem access, no network access, no environment variables, no syscalls — unless the host runtime explicitly provides them via imported functions.
- The host controls exactly which functions the module can call and what data it can see.
This is fundamentally different from a container or a subprocess, which inherit capabilities from the operating system and must be restricted by removing them (seccomp profiles, capability dropping, namespace isolation). Wasm starts with nothing and adds capabilities explicitly — a model called capability-based security.
+--------------------------------------------------+
| Host Application |
| |
| +--------------------------------------------+ |
| | Wasm Runtime (e.g., Wasmtime, Wazero) | |
| | | |
| | +--------------------------------------+ | |
| | | Wasm Module | | |
| | | | | |
| | | - Linear memory (bounded) | | |
| | | - No filesystem access | | |
| | | - No network (unless allowed) | | |
| | | - No env vars | | |
| | | - Only calls host functions | | |
| | | explicitly imported | | |
| | +--------------------------------------+ | |
| | | |
| | Host Functions (granted by config): | |
| | - Filesystem (specific paths only) | |
| | - Network (allowlisted hosts) | |
| | - Application-specific APIs | |
| +--------------------------------------------+ |
+--------------------------------------------------+
WASI — WebAssembly System Interface
For Wasm to be useful outside the browser, modules need a standardized way to interact with the outside world. WASI (WebAssembly System Interface) is a set of W3C standards-track API specifications that define how Wasm modules can:
- Read and write files (only those explicitly passed in by the host)
- Access clocks and random number generators
- Perform network operations (in newer versions)
Without WASI, each host application would define its own ad-hoc set of imported functions. WASI provides a common vocabulary so that a .wasm module compiled against WASI can run on any compliant runtime.
WASI versions
- Preview 1 (P1) — stable, widely supported. Provides basic file I/O and environment access through a POSIX-like API (POSIX = Portable Operating System Interface, the standard Unix API family). Most existing Wasm toolchains target P1.
- Preview 2 (P2) — adds the Component Model, which enables composing modules written in different languages into a single application. Components communicate through typed interfaces defined in WIT (Wasm Interface Type) files. P2 is the foundation for projects like wasmCloud that build distributed applications from composable Wasm components.
Wasm runtimes
A Wasm runtime is the engine that actually executes .wasm modules. WASI defines the interface (what system calls a module can make); the runtime provides the implementation (how those calls map to the host OS). Different runtimes target different use cases:
| Runtime | Language | Notes |
|---|---|---|
| Wasmtime | Rust | Reference runtime from the Bytecode Alliance. Full WASI P1 + P2 support. Used by Fermyon Spin, wasmCloud. |
| V8 | C++ | Powers Chrome, Node.js, and Envoy proxy. Primarily browser-focused but also used server-side via Node/Deno. |
| Wazero | Go | Pure Go, no CGO dependency. Used by Go projects that want to embed Wasm without a C toolchain. Helm 4 uses Wazero. |
| Wasmer | Rust | Extends WASI with WASIX (a superset adding threads, sockets, and process spawning). |
The Bytecode Alliance is a nonprofit organization (founded by Mozilla, Fastly, Intel, and Red Hat) that stewards Wasmtime and several WASI specifications.
Extism
See Extism for the full picture: architecture, Host SDKs, PDKs, and security model.
Extism is a framework (by Dylibso) that wraps a Wasm runtime and provides a higher-level plugin API — Plugin.Call(funcName, input) -> output — handling module instantiation, memory management, and data marshalling. Helm 4 uses Extism with Wazero as its Wasm plugin runtime.
Wasm in the Kubernetes ecosystem
Several CNCF (Cloud Native Computing Foundation) projects bring Wasm into different layers of the Kubernetes stack. The common thread is capability-based security: start with zero capabilities and explicitly grant only what is needed.
Wasm as an alternative compute runtime (instead of containers)
Traditional Kubernetes Pods run OCI (Open Container Initiative) container images inside Linux namespaces and cgroups. Wasm offers a different model: instead of isolating an entire Linux userspace, you run a single Wasm module with explicit capabilities.
Krustlet (2020–2022, Microsoft) was the first attempt — a kubelet replacement written in Rust that could schedule Wasm workloads on dedicated nodes. It proved the concept but was archived in 2023 because the approach of replacing the kubelet was too disruptive.
The current approach is containerd shims — plugins for containerd (the container runtime) that handle Wasm modules alongside regular containers:
- runwasi — a library that implements the containerd shim API for Wasm runtimes. Developed under the Bytecode Alliance.
- containerd-wasm-shim (specifically the Spin shim) — uses runwasi to let containerd execute Spin applications (Spin is Fermyon’s open-source framework for building Wasm microservices).
SpinKube is the CNCF project that ties this together. It was announced in March 2024 with contributions from Fermyon, Microsoft, SUSE, and Liquid Reply. SpinKube has four components:
- Containerd Spin Shim — the containerd plugin that executes Wasm modules.
- Runtime Class Manager (successor to KWasm) — a Kubernetes operator that annotates nodes and configures containerd to support the Spin shim.
- Spin Operator — a Kubernetes operator that manages
SpinAppcustom resources, making Wasm workloads feel like regular Kubernetes deployments. - Spin CLI Kubernetes Plugin — developer workflow:
spin new→spin build→spin registry push→spin kube scaffold→kubectl apply.
Why bother? The numbers are compelling: a Spin “hello world” compiles to a ~284 KiB binary (vs. tens of megabytes for a minimal container image), starts in sub-millisecond time (vs. seconds for containers), and runs in a sandboxed environment by default. This makes Wasm attractive for edge computing, serverless functions, and high-density multi-tenant workloads.
- wasmCloud — a CNCF Sandbox project that builds distributed applications from Wasm components communicating over NATS (a lightweight messaging system). Takes the Component Model further than SpinKube by fully decoupling business logic from infrastructure concerns.
Policy engines: OPA policies compiled to Wasm
OPA (Open Policy Agent) is a general-purpose policy engine that uses a language called Rego (a declarative query language designed for expressing policies over structured data). In Kubernetes, OPA powers Gatekeeper — an admission controller that evaluates policies before resources are created or modified.
OPA can compile Rego policies into Wasm modules using opa build -t wasm. The compiled module represents a pre-planned evaluation path — not the full OPA server. The host application loads the Wasm module, passes in the input document (e.g., a Kubernetes admission review), and gets back a policy decision.
This matters because:
- Performance: the Wasm module evaluates policies without starting an OPA process or making HTTP calls.
- Portability: the same
.wasmfile can run in any environment with a Wasm runtime — Kubernetes admission controllers, API gateways, CI pipelines, or edge devices. - Security: the policy evaluation itself runs in a Wasm sandbox.
Service mesh: Envoy Wasm filters
Envoy (the L4/L7 proxy used by Istio, Linkerd, and other service meshes) supports extending its request processing pipeline with Wasm filters. The mechanism uses the proxy-wasm ABI (Application Binary Interface) — a standardized interface between the proxy and Wasm modules.
A Wasm filter can inspect and modify HTTP headers, route requests, enforce rate limits, or add authentication logic — all without recompiling Envoy. The filter runs inside Envoy’s Wasm runtime (V8 or Wasmtime) with access only to the proxy-wasm API, not to the host filesystem or network stack.
This replaced Envoy’s older extension model (Lua scripts or compiled C++ filters) with something more portable and securely sandboxed. Istio adopted proxy-wasm as its primary extensibility mechanism.
See also
- Extism — cross-language Wasm plugin framework used by Helm 4, Zellij, and others
- Helm and WebAssembly — how Helm 4 uses Wasm for sandboxed plugins
- LLVM — Wasm is an LLVM compilation target