A wonderfully quick, compact, and extensible WebAssembly runtime for Go
Wago is pre-release. Wago-owned codecs and format contracts use version 1; see VERSIONING.md.
curl -fsSL https://install.wago.sh/unix | shOn Windows, use the command for your shell:
irm https://install.wago.sh/ps | iexcurl -fsSL https://install.wago.sh/cmd | cmdThe bootstrap scripts download the same checksummed Go installer for their platform, then hand off the complete interactive installation flow. Go is only needed when a release manager is unavailable and must be built from source.
For the Go package:
go get github.com/wago-org/wagoRead Getting started for installation details, release channels, profiles, and source builds.
Download a small module and run an exported function:
curl -fsSLo fib.wasm \
https://raw.githubusercontent.com/wago-org/wago/main/tests/fixtures/wasm/fib.wasm
wago run --invoke fib fib.wasm 20fib(20) = 6765
run is the default command:
wago fib.wasm 20
wago run --core 3 --invoke main generated-wasmgc.wasmOn complete backends, the CLI defaults on tail calls, typed function references,
multi-memory, memory64, and table64. WasmGC and exception handling remain opt-in:
pass --core 3 for the complete CoreFeaturesV3 set, or --core 2 for the
strict Release 2 set.
Validate or precompile a module:
wago validate fib.wasm
wago build fib.wasm -o fib.wago
wago run --invoke fib fib.wago 20Build a command module as a standalone native executable:
wago compile app.wasm -o app
wago compile app.wasm --target linux/arm64 -o app-linux-arm64
wago compile fib.wasm --invoke fib -o fib
wago compile component.wasm --core 3 -p -o component
./fib 20
# fib(20) = 6765By default, the module must export _start. Pass --invoke <name> to bake in a
different exported function; executable arguments are parsed from its typed Wasm
signature just like wago run --invoke. The executable embeds Wago, the Wasm
module, and the active local or global plugin configuration, so it runs without
a Wago installation. Use --bare, --local, or --global to choose the plugin
scope. Add plugins to wago.json before compiling so resolution, Authorities,
and Contract bindings stay reviewable and reproducible. --core 3, --parallel,
and compiler flags such as --no-inline and --no-deferred-bounds-checking are
baked into the executable.
There is no standalone watch mode because the module is immutable once embedded.
Cross-builds support Darwin, Linux, and Windows on AMD64 and ARM64.
Inspect its host requirements:
wago module imports fib.wasm
wago module exports fib.wasm
wago module capabilities fib.wasmSee Run a module for typed arguments,
watch mode, parallel compilation, .wago artifacts, and runtime flags.
Create a project and add the WASI plugin:
wago init --run
wago add github.com/wago-org/wasi
wago run program.wasm hello worldwago add resolves the complete dependency and Contract graph, reviews exact
scoped Authorities, pins sources and bindings in wago-lock.json, verifies the
linked definitions, and atomically publishes the rebuilt runtime.
Useful plugin commands:
wago plugin list
wago plugin list --json
wago plugin inspect github.com/wago-org/wasi
wago plugin tree
wago plugin grant github.com/wago-org/wasi
wago plugin grant github.com/wago-org/wasi --scopes '{"github.com/wago-org/wasi":{"host.import.define":{"modules":["wasi_snapshot_preview1"]}}}'
wago plugin config github.com/wago-org/wasi '{"stdout":"discard"}'
wago plugin update
wago plugin rebuild --locked
wago plugin remove github.com/wago-org/wasiBrowse packages at plugins.wago.sh. Read Use plugins for local and global scopes, Authorities, Contracts, lockfiles, and publishing.
Compile a module, create an instance, and call an export:
package main
import (
"context"
"fmt"
"os"
"github.com/wago-org/wago"
)
func main() {
wasmBytes, err := os.ReadFile("fib.wasm")
if err != nil {
panic(err)
}
rt := wago.NewRuntime()
defer rt.Close()
mod, err := rt.Compile(wasmBytes)
if err != nil {
panic(err)
}
ctx := context.Background()
inst, err := rt.Instantiate(ctx, mod)
if err != nil {
panic(err)
}
defer inst.Close()
out, err := inst.Call(ctx, "fib", wago.ValueI32(20))
if err != nil {
panic(err)
}
fmt.Println(out[0].I32()) // 6765
}Read Embed Wago in Go for compilation, instances, typed values, memory, cancellation, and cleanup.
Host functions use one reflection-free stack form under standard Go and TinyGo:
mul := wago.HostFunc(func(_ wago.HostModule, params, results []uint64) {
a := wago.AsI32(params[0])
b := wago.AsI32(params[1])
results[0] = wago.I32(a * b)
})
inst, err := rt.Instantiate(context.Background(), mod, wago.WithImports(wago.Imports{
"host.mul": mul,
}))HostModule gives the function access to the calling instance and its linear
memory.
Read Host functions for signatures,
memory access, errors, and capability policy. More runnable programs live in
examples/.
# Pick or update a runtime
wago version install canary
wago version switch
wago update
# Work with project plugins
wago init
wago add github.com/wago-org/wasi github.com/wago-org/workers
wago plugin outdated
wago plugin tree
# Inspect and maintain Wago
wago status
wago config
wago cache size
wago cache clean
# Use Wago from scripts or agents
wago --no-input version install --canary \
--profile standard --build normal --use
wago update --all --no-input --dry-run --json
wago commands --jsonEvery interactive workflow has flags for one-shot use. Read the
configuration reference or run
wago <command> --help for the exact options.
Wago compiles validated functions directly to native code in a single pass. The published benchmark suite compares Wago and wazero within each architecture on the same modules and machine.
These numbers come from the published July 30, 2026 snapshot at Wago
ff87ac3.
Architectures were measured on different machines, so compare values across a
row, not between the amd64 and arm64 tables.
| Benchmark | Wago | wazero |
|---|---|---|
Compile fib_rec |
4 µs | 44.9 µs |
Instantiate fib_rec |
2.1 µs | 8.7 µs |
| Host → Wasm call | 10.4 ns | 33.1 ns |
| Wasm → host → Wasm | 148.5 ns | 440.4 ns |
| Execute recursive fib | 370 µs | 538 µs |
| JSON deserialize | 40 µs | 63.6 µs |
| Execute ray tracer | 401 µs | 367 µs |
| Compile esbuild, Go heap | 74.2 MB | 256.2 MB |
| Benchmark | Wago | wazero |
|---|---|---|
Compile fib_rec |
3.3 µs | 25.6 µs |
Instantiate fib_rec |
550.4 ns | 8.9 µs |
| Host → Wasm call | 18.7 ns | 23.9 ns |
| Wasm → host → Wasm | 119.9 ns | 315.5 ns |
| Execute recursive fib | 260 µs | 387 µs |
| JSON deserialize | 40.4 µs | 44 µs |
| Execute ray tracer | 275 µs | 255 µs |
| Compile esbuild, Go heap | 82.2 MB | 262.7 MB |
Go heap rows exclude guest linear memory, native code mappings, virtual-memory reservations, RSS, and PSS.
Spawn-to-exit wall-clock latency, including process startup, compilation, instantiation, and execution:
| Workload | Wago | Closest result |
|---|---|---|
| json-as | 5.1 ms | wasmi 7.4 ms |
| nbody | 30.9 ms | wasmtime 30.1 ms |
| spectral norm | 3.7 ms | wazero 4.8 ms |
| quicksort | 9.4 ms | wasmtime 10.8 ms |
| ray tracer | 9.0 ms | wazero 8.8 ms |
| SHA-256 | 2.4 ms | wazero 2.9 ms |
See wago.sh/#performance for the full tables.
The benchmark corpus and methodology are in bench/.
Run them locally:
cd bench
go test -bench . -benchmemWago supports the WebAssembly 1.0 core language and the implemented
WebAssembly 2.0 release features, including multi-value, reference types, bulk
memory, extended constant expressions, and SIMD. Native runtime paths, CI, and
release assets cover Linux, macOS, and Windows on amd64 and arm64. Linux amd64
is the primary performance target. Selected Core 3 families default on for
linux/amd64, linux/arm64, and darwin/arm64; the complete set is available there
with --core 3.
Wago has no interpreter tier: supported modules execute as native machine code.
Source modules can be compiled in the running process, serialized as native
.wago artifacts for later loading, or embedded in standalone native
executables. Standalone executables compile their embedded Wasm at startup;
.wago artifacts instead load previously generated code for the target
architecture and runtime configuration. Unsupported or disabled features fail
during decode or validation.
Read the Wago documentation for guides and reference material. The repository also keeps the detailed feature matrix, architecture notes, and roadmap.
make lint
make test
make test-guardRun make to list build, test, conformance, benchmark, and release targets.
Read CONTRIBUTING.md before opening a pull request.
Wago is distributed under the Apache License 2.0.