Prerequisites: WebAssembly
What is WebAssembly?
The WebAssembly System Interface
Overview of Go's Existing WebAssembly Support
WASI Support in the Go Toolchain
Demonstration
The future of Wasm in Go
WebAssembly (Wasm) is a binary instruction format originally designed for the web. It represents a standard that allows developers to run high-performance, low-level code directly in web browsers at near-native speeds.
Go first added support for compiling to Wasm in the 1.11 release through the js/wasm
port. This enabled Go code compiled using the Go compiler to be executed in web browsers, albeit requiring a JavaScript execution environment.
As the use of Wasm has grown, so have the use cases outside of the browser. Many cloud providers are now offering services that enable users to execute Wasm executables directly, leveraging the new WebAssembly System Interface (WASI) syscall API.
WASI defines a system for WebAssembly (Wasm) programs to communicate with computer resources like the filesystem, system clock, and random data utilities. The most recent WASI specification is known as wasi_snapshot_preview
1, leading to the GOOS
name wasip1
. Future versions of the API are in development, and incorporating them into the Go compiler might mean introducing a new GOOS.
The establishment of WASI has enabled various Wasm runtimes (hosts) to standardize their communication with the system through this API. Examples of Wasm/WASI hosts encompass Wasmtime, Wazero, WasmEdge, Wasmer, NodeJS. Additionally, several cloud providers offer hosting for Wasm/WASI executables.
Go 1.21 adds a new port targeting the WASI preview 1 syscall API through the new GOOS
value wasip1
. This port builds on the existing WebAssembly port introduced in Go 1.11.
Along with the new wasip1/wasm
port, Go 1.21 also brings a new compiler instruction called go:wasmimport
. This instruction tells the compiler to change calls to a specific function into calls to another function specified by the host module and function name. This new feature in the compiler helped us create the wasip1
syscall API in Go for the new port, but it can be used for more than just the standard library.
wasip1
API lacks comprehensive network socket functionality, hindering support for key features like HTTP servers from the Go standard library.go:wasmimport
, enables net.Dial
and net.Listen
on compatible Wasm hosts, facilitating the creation of net/http
servers and other network-related functionalities.Make sure that you have installed at least version 1.21 of Go. For this demo, we’ll use the Wasmtime host to execute our binary.
package main
import "fmt"
func main() {
fmt.Println("Hello wasip1!")
}
We can build it for wasip1
using the command:
$ GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
This will produce a file, main.wasm
which we can execute with wasmtime
:
$ wasmtime main.wasm
Hello wasip1!
Overall, these advancements position Go to play a significant role in the future of the Wasm ecosystem.
Portfolio: https://iamrajiv.github.io
GitHub: https://github.com/iamrajiv
LinkedIn: https://www.linkedin.com/in/iamrajivranjansingh
Twitter: https://twitter.com/therajiv