wasm-basics
wasm-basics copied to clipboard
This repository contains information, references, and samples about running WebAssembly outside the browser
WebAssembly outside the browser
This repository contains information, references, and samples about running WebAssembly (Wasm) outside the browser.
WebAssembly: Why? What?
What is WebAssembly?
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.
Wasm outside the browser
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/amd64won’t work onwindows/amd64or evenlinux/arm64. Wasm creates a singlewasm32/wasimodule that runs everywhere in a Wasm runtime on any host.
WASI
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).
Wasm Runtimes
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.
Relevant specs and projects
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.tomlmatching 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
wasmerruntime right now.
Running Wasm in containers
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.
runwasi
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.
Vendors and Frameworks for Wasm+Wasi
These are some notable vendors and frameworks supporting Wasm+Wasi.
Docker
Starting in Docker Desktop 4.15, Docker uses runwasi to support Wasm workloads running in the following runtimes:
wasmedgewasmtimespinfrom Fermyonslightfrom Deislabs
See Announcing Docker+Wasm Technical Preview 2 for more details.
Azure
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
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.
Slight
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.
Languages supported in Wasm+WASI
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.
Samples
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.
References
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: