blog

12022-04-15

SEAN K.H. LIAO

WebAssembly

WebAssembly (Wasm) "is a binary instruction format for a stack-based virtual machine". In plainer words, wasm is a format of an executable that a compiler can compile to and a runtime can run.

How is this different from say the Java Virtual Machine (JVM)? Arguably, within the JVM ecosystem, the JVM came first and languages were designed for it and around its perculiarities. Wasm came much later, instead targeting existing languages by exposing a lower level, more minimal interfaces that existing languages/compilers can target as just another architecture.

Wasm itself is fairly low-level, so on top of that, there's a Web API for integration with browsers, JavaScript API for JS, and WASI for a generic interface for life outside the web/browser.

Writing Wasm

Go: While go has a GOOS=js GOARCH=wasm target, it targets the web, and also requires extra js to setup everything. Instead, you'll want tinygo

TinyGo: Go, but targeting embedded systems and wasm. It's not a full drop in replacement (see language support), but good enough.

Rust: Supports a wasm-wasi target at Tier 2, most tutorials will have you writing rust.

Packaging and Distrobution

You have code, and you have a compiled binary that can run everywhere (that a runtime supports), so how do you get that from your development machine to your deployment machine?

Most projects appear to be piggybacking on top of the Open Containers Initiative (OCI) artifacts, who have defined a well supported image/metadata format that can support arbitrary data. Alternatives include wasmer wapm, wasm-pack on top of NPM, bindle for Hippo, bundle for Suborbital / Atmo, etc.

Running Wasm

As a non native (hardware) instruction format, code compiled to wasm needs a runtime to run. There are quite a few, some are simple runtimes, while others are part of a wider development/deployment suite. Some notable ones:

WasmEdge integrates with crun / containerd, allowing projects that use those (K8s and its extended ecosystem) to easily schedule / manage / run wasm code.

Krustlet integrates directly with the kubernetes API, exposing itself as a node/kubelet that can run wasm binaries from OCI registries.

Suborbital / Atmo, wasmCloud, Hippo all look like integrated build tooling + deployment platform / servers.

Alternatively, you can also use wasm for libraries / plugins, exposing functions instead of a full application. For Go: Wasmtime, WasmEdge Wasmer all provide SDKs that make it easy.