Home

Awesome

Build Go Reference Apache 2 License

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:

LanguageLibrary
Gostealthrocket/net
Pythonstealthrocket/timecraft (Python SDK)
Rustsecond-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:

Featurewazero/imports/wasi_snapshot_preview1wasi-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:

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!