Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Write a module

This page is for a module author. It takes you from guestfn init to a module published as an OCI artifact, using the Go scaffold as the worked example. The other scaffolds (--lang rust, zig, c, ts or python) use the same commands. See Other languages for what differs.

Install the CLI and scaffold a project:

cargo install --git https://github.com/jonasz-lasut/function-wasm guestfn

guestfn init greeter --module github.com/example/greeter   # --lang go (default), rust, zig, c, ts or python
cd greeter

The Go scaffold writes fn.go, fn_test.go and main.go. fn.go is a plain function-sdk-go RunFunction that composes a ConfigMap greeting the composite resource, with no code specific to WebAssembly. main.go only registers it:

func init() {
	wasmfn.Register(&Function{log: wasmfn.NewLogger(), http: wasmfn.HTTPClient()})
}

func main() {}

The glue is a small internal/wasmfn package that the project owns. It exports run for the ABI v2 world: it decodes the request, calls your RunFunction and encodes the response. It also provides a logging.Logger over the runtime’s typed log import, and wasmfn.GetConfig(req, &cfg) to read the Input’s config block. The Go bindings under internal/bindings are written by wit-bindgen and checked in.

examples/pdb-addon is a Go module built on what guestfn init writes. Its internal/wasmfn, wit/ and internal/bindings are the scaffold’s, byte for byte.

Build, inspect and publish

go test ./...                                   # unit tests run natively
guestfn build                                   # fn.wasm (an ABI v2 component); prints the ABI verdict and the manifest summary
guestfn inspect fn.wasm                         # size, ABI verdict, exports, imports
guestfn push ghcr.io/example/greeter:v0.1.0     # OCI artifact with the manifest; prints the module block and what the module requires

guestfn build runs go build, embeds the world from wit/ and wraps the result into a component. It then compiles the component with the runtime’s own Wasmtime engine and prints the verdict a load gives. For the Go scaffold the output is a Componentized fn.wasm (wasip1 adapter linked) line, then a Built line with the file, its size, ABI v2, the world’s imports and the manifest summary.

A module the runtime would refuse fails the build with the runtime’s own words, and guestfn push refuses to publish it for the same reason. The refusals are listed in Troubleshooting.

guestfn inspect fn.wasm shows what the runtime sees: size, verdict, exports and imports. guestfn inspect ghcr.io/example/greeter:v0.1.0 describes a published artifact from its manifest without pulling it, and --pull reads the module too. --output json prints JSON for scripts.

Manifest

The scaffold includes a wasmfn.yaml, the module’s manifest. It gives the module a name and version, declares the sandbox capabilities the module can’t run without, and contains the JSON Schema of its config. guestfn build validates it and guestfn push publishes it beside the module. See Module manifests for the fields and for how the runtime checks a module’s requirements.

guestfn scaffold composition --from ghcr.io/example/greeter:v0.1.0 (or --from fn.wasm) writes a Composition step for the module, pinned by digest, with a config skeleton from the schema and a commented compositionPolicy skeleton. The policy block is a commented starting point for narrowing. --full writes a whole Composition.

What guestfn push publishes

guestfn push produces a CNCF Wasm OCI artifact: one application/wasm layer, the manifest as an application/vnd.wasmfn.manifest.v1+json layer when the project has one, a config object listing both digests in layerDigests, and the standard org.opencontainers.image.* annotations from the manifest.

oras push ghcr.io/example/greeter:v0.1.0 fn.wasm:application/wasm wasmfn.json:application/vnd.wasmfn.manifest.v1+json gives the same result. A FROM scratch image whose only layer copies the module to /fn.wasm works too, without a manifest. The runtime reads that exact path and doesn’t search the archive.

Module size

A Go module that uses function-sdk-go’s helpers is about 75 MB. See Sizing for what that costs the runtime.