Awesome
WASI
The WebAssembly System Interface (WASI) is a set of standard system functions that allow WebAssembly modules to interact with the outside world (e.g. perform I/O, read clocks).
The WASI standard is under development. This repository provides a Go implementation of WASI preview 1 for Unix systems, and a command to run WebAssembly modules that use WASI.
Motivation
WASI preview 1 was sealed without a complete socket API, and WASI as a standard is still a moving target.
Some WebAssembly runtimes have taken the initiative to either extend WASI preview 1 or provide alternative solutions for capabilities that were missing from the core specification, enabling a wider range of applications to run as WebAssembly modules.
This package intends to bundle WASI preview 1 and these extensions with the wazero runtime, and more generally be a playground for experimentation with cutting-edge WASI features.
:electric_plug: Sockets
This library provides all the socket capabilities specified in WASI preview 1, as well as a full support for a socket API which is ABI-compatible with the extensions implemented in the wasmedge runtime.
Applications interested in taking advantage of the socket extensions may be interested in those libraries:
Language | Library |
---|---|
Go | stealthrocket/net |
Python | stealthrocket/timecraft (Python SDK) |
Rust | second-state/wasmedge_wasi_socket |
:zap: Performance
The provided implementation of WASI is a thin zero-allocation layer around OS system calls. Non-blocking I/O is fully supported, allowing WebAssembly modules with an embedded scheduler (e.g. the Go runtime, or Rust Tokio scheduler) to schedule goroutines / green threads while waiting for I/O.
:battery: Experimentation
The library separates the implementation of WASI from the WebAssembly runtime host module, so that implementations of the provided WASI interface don't have to worry about ABI concerns. The design makes it easy to wrap and augment WASI, and keep up with the evolving WASI specification.
Non-Goals
wasi-go
does not aim to be a drop-in replacement for the wasi_snapshot_preview1
package that ships with the wazero runtime. For example, the wasi-go
package does not build on Windows, nor does it allow customization of the file
systems via a fs.FS
.
The following table describes how users should think about capabilities of wazero and wasi-go:
Feature | wazero/imports/wasi_snapshot_preview1 | wasi-go/imports/wasi_snapshot_preview1 |
---|---|---|
WASI preview 1 | ✅ | ✅ |
Windows Support | ✅ | ❌ |
WasmEdge Socket Extensions | ❌ | ✅ |
Usage
As a Command
A wasirun
command is provided for running WebAssembly modules that use WASI host imports.
It bundles the WASI implementation from this repository with the wazero runtime.
$ go install github.com/stealthrocket/wasi-go/cmd/wasirun@latest
The wasirun
command has many options for controlling the capabilities of the WebAssembly
module, and for tracing and profiling execution. See wasirun --help
for details.
As a Library
The package layout is as follows:
.
types, constants and an interface for WASI preview 1systems/unix
a Unix implementation (tested on Linux and macOS)imports/wasi_snapshot_preview1
a host module for the wazero runtimecmd/wasirun
a command to run WebAssembly moduleswasitest
a test suite against the WASI interface
To run a WebAssembly module, it's also necessary to prepare clocks and "preopens" (files/directories that the WebAssembly module can access). To see how it all fits together, see the implementation of the wasirun command.
With Go
As the providers of a Go implementation of WASI, we're naturally interested in Go's support for WebAssembly and WASI, and are championing the efforts to make Go a first class citizen in the ecosystem (along with Rust and Zig).
Go v1.21 has native support for WebAssembly and WASI:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
# go version
go version go1.21.0 darwin/arm64
$ GOOS=wasip1 GOARCH=wasm go build -o hello.wasm hello.go
$ wasirun hello.wasm
Hello, World!
This repository bundles a script that can be used to skip the
go build
step.
Contributing
Pull requests are welcome! Anything that is not a simple fix would probably benefit from being discussed in an issue first.
Remember to be respectful and open minded!