This repository contains information, references, and samples about running WebAssembly (Wasm) outside the browser.
WebAssembly (Wasm) is a binary instruction format for a stack-based virtual machine and a portable compilation target for programming languages.
The original use cases were focused on running native code in web browsers in a fast, portable, and secure way. Supported by all major browsers.
More recently, there’s an attempt to get WebAssembly run outside the browser with the WASI project. The idea is instead of running apps as VMs or containers, you can run them as faster, smaller, more secure, and more portable WebAssembly modules:
- Faster: Wasm apps start much faster than containers with no cold-start.
- Smaller: A HelloWorld Rust app in Wasm is much smaller than in an OCI container.
- More secure: Containers execute in an allow-by-default model whereas Wasm apps execute in a deny-by-default sandbox.
- More portable: A container built for
linux/amd64
won’t work onwindows/amd64
or evenlinux/arm64
. Wasm creates a singlewasm32/wasi
module that runs everywhere in a Wasm runtime on any host.
Wasm code outside of a browser needs a way to talk to the system — a system interface and that’s what WebAssembly System Interface (WASI) provides. Wasm runtimes implement WASI.
A lot of WASI is still in proposals and limited. For example, networking is not
yet part of the WASI standard (so, no socket support in your Wasm module).
However, some Wasm runtimes like wasmedge
(see WasmEdge WASI
Socket) and wasmtime
implement their own POSIX sockets. There are projects like
WAGI to wrap HTTP handlers around Wasi (and
frameworks like Spin use WAGI) or
WASIX to add networking, multi-threading and more to WASI
(but only supported on wasmer
runtime for now).
In Wasm, instead of compiling to an OS and architecture such as linux/arm64
,
you compile to WebAssembly (wasm32/wasi
). Wasm has its own bytecode format
that needs to run in a Wasm runtime.
Many wasm runtimes exist (see awesome-wasm-runtimes), some of the popular ones are:
- wasmtime: A Bytecode Alliance project, designed to run on servers and the cloud.
- wasmer: Another popular Wasm runtime from a startup.
- wasmedge: A CNCF project, with more focus on edge devices.
There are relevant specs and projects (that I haven’t looked in too much detail):
- WebAssembly Component Model: WASI is layered on top of the Component Model, with the Component Model providing the foundational building blocks used to define WASI’s interfaces. In comparison to traditional Operating Systems, the Component Model fills the role of an OS's process model (defining how processes start up and communicate with each other) while WASI fills the role of an OS's many I/O interfaces.
- WAGI: WebAssembly Gateway Interface allows
you to run WebAssembly WASI binaries as HTTP handlers. Write a command line
application that prints a few headers, and compile it to
wasm32/wasi
. Add an entry to themodules.toml
matching URL to the Wasm module and that’s it. - WASIX: WASIX is the long term stabilization and support
of the existing WASI plus additional non-invasive syscall extensions (e.g.
networking, multi-threading) that complete the missing gaps sufficiently
enough to enable real, practical and useful applications to be compiled and
used now. It aims to speed up the ecosystem around the WASI so that the
Wasm’ification of code bases around the world can really start. Only supported
in
wasmer
runtime right now.
There’s ongoing work to run Wasm inside of containers. This might seem counterintuitive — why take something smaller, faster, and more portable than a container and run it inside a container? Running Wasm apps inside of a container gets you the security benefits of the Wasm sandbox and the benefits of the existing toolchain like Docker, Kubernetes.
Kubernetes relies on a container runtime called
containerd (which in turn relies on runc
) to manage
the lifecycle of containers. runwasi is a
project to integrate Wasm runtimes with containerd
to enable containerd
to
manage the lifecycle of Wasm apps. Currently, wasmtime
and wasmedge
runtimes
are supported in runwasi
.
These are some notable vendors and frameworks supporting Wasm+Wasi.
Starting in Docker Desktop 4.15, Docker uses runwasi
to support Wasm workloads running in the following runtimes:
wasmedge
wasmtime
spin
from Fermyonslight
from Deislabs
See Announcing Docker+Wasm Technical Preview 2 for more details.
Azure AKS is also previewing Wasm node pools using runwasi
. Currently, there are only containerd
shims available for spin and slight applications, which use the wasmtime
runtime.
Spin by Fermyon is a WebAssembly framework for building and running event-driven microservice applications with WebAssembly (Wasm) components. Spin handles the HTTP request/response using WAGI HTTP Executor. Spin SDKs are available in Rust, Go and .NET. and all Wasi-compatible languages are supported. Additionally, Fermyon Cloud service fetches source code from the GitHub repo, builds it into Wasm bytecode, runs it as a serverless microservice, and connects HTTP input and output to it using Spin framework.
SpiderLightning is a set of WIT interfaces that abstract distributed application capabilities (such as key-value, messaging, HTTP server/client) and a runtime CLI for running Wasm applications that use these capabilities.
Here’s a comprehensive list of languages from Fermyon and WASI language support (part 1) from Enarx. The Complex World of Wasm Language Support provides the context.
It's not so clear what languages are really supported on Wasm/Wasi outside the browser at what level. Most languages, such as .NET, are experimental with Wasm/Wasi support at best and changing constantly. Other languages, like Java, have some support for Wasm via projects like TeaVM but geared more towards browsers.
These are some samples in this repo:
- rust-wasm - Running Rust on Wasm.
- dotnet8-wasm - Running .NET 8 (preview) on Wasm.
- go-wasm - Running Go on Wasm.
- kotlin-wasm - Running Kotlin on Wasm with kowasm by James Ward.
- rust-wasm-docker - Running Rust on Wasm in Docker.
- hello-wagi - Running WASI binaries as HTTP handlers with WAGI.
- python-spin-wasm - Running Python with Spin on Wasm.
WASI:
Docker + Wasm:
- Announcing Docker+Wasm Technical Preview 2
- Introducing the Docker+Wasm Technical Preview
- Docker + Wasm (Beta)
Azure + Wasm:
Fermyon blog:
Nigel Poulton’s blog:
- WebAssembly: The future of cloud computing
- What is cloud native WebAssembly?
- What is runwasi?
- Getting started with Docker + Wasm
- WebAssembly and containerd: How it works
Wasm By Example:
WebAssembly for different languages:
- WebAssembly support in Top 20 languages by Fermyon
- WASI language support (part 1)
- Enarx - WebAssembly Introduction
- WASI support on .NET 8
- The JVM Meets WASI: Writing Cloud-Friendly Wasm Apps Using Java and Friends - Joel Dice
Talks at Cloud Native Wasm Days: