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.
--lang | example | toolchain | Protobuf codec | module size |
|---|---|---|---|---|
go (default) | examples/pdb-addon | Go | function-sdk-go’s request/response/resource helpers | ~75 MB |
rust | examples/cloudflare-origin | Rust 1.100+, target wasm32-wasip3, cargo and protoc | prost over the vendored proto | ~240 KB scaffolded, ~315 KB for the example |
zig | examples/hello-zig | Zig 0.16 | zig-protobuf over the vendored proto | ~60 KB |
c | examples/hello-c | C compiled by zig cc | nanopb over the vendored proto | ~62 KB |
ts | examples/policy-gate | node and npm | protobuf-es over the vendored proto | ~14 MB (SpiderMonkey) |
python | examples/team-tags | python3 | protoc’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 buildcompiles 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 bymake build. It reuses thecflavour’s bindings, nanopb codec, WIT and proto. Odin compiles the guest to an object,zig cclinks it with the C half, andguestfn buildtreats the project as acone and wraps it without an adapter.make testruns the unit tests natively. - MoonBit:
examples/hello-moonbit, ~107 KB, built withmoon(version0.1.20260920). It uses wit-bindgen’s MoonBit bindings and the protoc-gen-mbt codec, regenerated bymake gen-bindingsandmake gen-proto.guestfn builddetects it bymoon.mod, embeds the world stated as UTF-16, MoonBit’s string encoding, and wraps it without an adapter. The unit tests run onmoonrun. A guest must never callprintln: it importsspectest.print_char.
Untested
- C++: no guest here.
- TinyGo: the scaffold was retired on 2026-10-07 (#114). The
goflavour is the Go path. - AssemblyScript: not supported, because it has no component path.