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

Other languages

This page is for a module author choosing a guest language. It lists the six flavours guestfn init scaffolds, the guests that exist only as examples, and what the project hasn’t tested. Pick a flavour, scaffold it, then follow Write a module. Any toolchain that produces a component for the ABI v2 world, wasmfn:function, works: the runtime checks the world and never the language.

Scaffolded flavours

guestfn init --lang <flavour> writes the same greeting function in each of these, and guestfn build detects the toolchain from the project. All six build an ABI v2 component, and the guest suite runs them through the host, and the example build jobs build, test and lint them, on every /e2e. The sizes are of the built module.

--langexampletoolchainProtobuf codecmodule size
go (default)examples/pdb-addonGofunction-sdk-go’s request/response/resource helpers~75 MB
rustexamples/cloudflare-originRust 1.100+, target wasm32-wasip3, cargo and protocprost over the vendored proto~240 KB scaffolded, ~315 KB for the example
zigexamples/hello-zigZig 0.16zig-protobuf over the vendored proto~60 KB
cexamples/hello-cC compiled by zig ccnanopb over the vendored proto~62 KB
tsexamples/policy-gatenode and npmprotobuf-es over the vendored proto~14 MB (SpiderMonkey)
pythonexamples/team-tagspython3protoc’s Python codec on the pure-Python protobuf runtime~21 MB (CPython)

Each flavour keeps its ABI glue in the project, so you own and can edit it. The sections below give each toolchain and how guestfn build finishes the component.

Go

The scaffold vendors internal/wasmfn over the Go bindings that wit-bindgen writes under internal/bindings. Both are checked in. make gen-bindings regenerates them with wit-bindgen-cli 0.62.0. Your function is a plain function-sdk-go RunFunction. go build emits a wasip1 reactor, and guestfn build embeds the world from the project’s wit/ and wraps the result into a component. run is sync-lifted, and an *http.Client reaches the host’s egress over wasi:http@0.2.

Rust

The rust flavour needs Rust 1.100 and the wasm32-wasip3 target. The scaffold’s rust-toolchain.toml pins the toolchain, which your Rust installer fetches on first use. run is async, and a fetch awaits wasi:http. See ABI v2 for the world.

Zig and the C flavour

Both compile with the zig binary and share wit-bindgen’s C bindings, checked in under src/gen and regenerated by make gen-bindings. Zig reads them through translate-c, and the C flavour compiles them with zig cc without wasi-sdk. run is sync-lifted, with wasi:http@0.2 fetch. The glue is beside the module in src/wasmfn.zig and src/wasmfn.c. zig links a core module without libc, and guestfn build wraps it into a component without an adapter or wasm-tools. protoc or nanopb_generator is needed only to regenerate the codec.

TypeScript

npm install is the whole toolchain. esbuild bundles the guest, and jco componentizes it with componentize-js. The types come from protobuf-es, the test gate runs tsc --noEmit, and the greeting comes from the platform’s fetch(), served over wasi:http@0.2 through the same egress policy as every other guest. run is sync-lifted because componentize-js can’t async-lift a custom world yet, and your TypeScript can still await. The scaffold has no package-lock.json: guestfn build runs npm install without one and npm ci with one.

Python

componentize-py is the toolchain, and guestfn build makes the venv from requirements.txt when the project has none. The guest bundles the pure-Python protobuf runtime, and run is sync-lifted. Fetches go over wasi:http@0.2 on componentize-py’s poll loop, through the same egress policy.

How build chooses a toolchain

guestfn build reads the project: Cargo.toml selects cargo, build.zig selects zig (both the zig and c flavours), package.json selects npm, requirements.txt selects componentize-py, go.mod selects go, and moon.mod or moon.mod.json selects moon. --lang overrides the choice, and build also accepts moonbit.

When a build leaves a core module, guestfn build wraps it into a component with the wasip1 adapter of the runtime’s own Wasmtime, which is the adapter version the runtime was built with. The zig and c builds already leave a core module with wit-bindgen’s component-type section, and guestfn build wraps it directly. For go and MoonBit, wit-bindgen writes bindings only, so guestfn build embeds the world from wit/ first.

Examples without a scaffold

These guests solve their own use case or show one more language. Each has unit tests in its language and a build job that checks its generated code for drift. guestfn init scaffolds none of them, and guestfn build detects only Odin (as a c project) and MoonBit.

  • C#: examples/dashboard-bundle, ~4.5 MB, needs the .NET 10 SDK. make build compiles it with NativeAOT-LLVM and componentize-dotnet, in the .NET SDK container on macOS, which has no NativeAOT-LLVM compiler.
  • Odin: examples/hello-odin, ~71 KB, built with Odin dev-2026-10 and Zig 0.16 by make build. It reuses the c flavour’s bindings, nanopb codec, WIT and proto. Odin compiles the guest to an object, zig cc links it with the C half, and guestfn build treats the project as a c one and wraps it without an adapter. make test runs the unit tests natively.
  • MoonBit: examples/hello-moonbit, ~107 KB, built with moon (version 0.1.20260920). It uses wit-bindgen’s MoonBit bindings and the protoc-gen-mbt codec, regenerated by make gen-bindings and make gen-proto. guestfn build detects it by moon.mod, embeds the world stated as UTF-16, MoonBit’s string encoding, and wraps it without an adapter. The unit tests run on moonrun. A guest must never call println: it imports spectest.print_char.

Untested

  • C++: no guest here.
  • TinyGo: the scaffold was retired on 2026-10-07 (#114). The go flavour is the Go path.
  • AssemblyScript: not supported, because it has no component path.