| name | wasm-build |
| description | Build WebAssembly components from Rust, Python, JavaScript/TypeScript, or Go using the Component Model. Defaults to WASI 0.3 (RC) for Rust and Python (native async / stream / future), and WASI 0.2 for JavaScript and Go (whose toolchains don't yet ship a p3 path). Covers scaffolding, language-specific toolchain setup (wit-bindgen, componentize-py, jco / componentize-js, tinygo), compilation, WIT binding generation, validation, and size/startup optimization. |
| allowed-tools | Bash, Read, Write, Edit, Glob, Grep, WebFetch |
wasm-build skill
You help users compile source code into WebAssembly components targeting the Component Model.
Last verified: 2026-04-30. Re-verify versions with WebFetch (or the repo's just check-versions recipe) before pinning new projects.
WASI version defaults
| Language | Default WASI version | Why |
|---|
| Rust | 0.3 RC (0.3.0-rc-2026-03-15) | wit-bindgen 0.57.1 generates stream<> / future<> / async fn cleanly; the wasm32-wasip2 rustc target produces a p3 component when the WIT imports p3. |
| Python | 0.3 RC (0.3.0-rc-2026-03-15) | componentize-py 0.23 ships shipped cli-p3 / http-p3 / tcp-p3 examples; async def exports map to async func. |
| JavaScript | 0.2 | jco@1.19 lacks the p3-shim; upstream main is in active dev. Track bytecodealliance/jco@main for a 1.20 release. |
| Go (TinyGo) | 0.2 | TinyGo has no wasip3 target; only wasip1 and wasip2. |
For wasm-build-multi polyglot groups, this means rs + py default to p3 and js + go default to p2 — and since p3 is fully back-compat for the host, all four can be composed and tested together. Override either default by pointing the WIT at the version you want and re-running wkg wit fetch.
Toolchain version pins
| Tool | Version | Purpose |
|---|
| Rust | stable (≥ 1.82) | wasm32-wasip2 target (works for both 0.2 and 0.3 components — see scripts/rust.md) |
wit-bindgen (Rust crate) | 0.57.1 | Binding generation via wit_bindgen::generate! macro |
componentize-py | 0.23.0 | Python → component (p2 + p3) |
@bytecodealliance/jco | 1.19.0 | JS toolchain (p2 only as of 1.19) |
@bytecodealliance/componentize-js | 0.20.0 | JS → component (still labeled experimental upstream) |
| TinyGo | 0.41.1 | Go → component (-target=wasip2) |
go.bytecodealliance.org | v0.7.0 | Go runtime + wit-bindgen-go; repo: bytecodealliance/go-modules |
wasm-tools | 1.248.0 | Validate, inspect, compose, adapt — pass --features all for any p3 component (stream<> / future<> / async func) |
wkg | 0.15.0 | WIT package fetch/build/publish |
wac | 0.10.0 | Component composition DSL |
wasmtime | 44.0.0 | Runtime — for p3 use -Sp3 -Wcomponent-model-async (add -Shttp for HTTP-importing components); supported since 43.0.0 |
Capabilities
When invoked, help users:
- Scaffold new components with WIT.
- Build source →
.wasm component.
- Validate with
wasm-tools validate and wasm-tools component wit.
- Manage WIT dependencies with
wkg.
- Compose multi-component apps with
wac.
- Optimize size and startup.
For running built components, defer to the wasmtime skill.
For publishing to OCI registries, defer to component by default; reach for wasm-toolchain (wkg) when you need raw OCI annotation control or WIT-package publishing.
Project layout
The repo keeps each component as a sibling source folder + built .wasm:
components/
├── my-component/ # source
│ ├── src/ or app.py / index.js / main.go
│ ├── wit/world.wit
│ ├── Cargo.toml | pyproject.toml | package.json | go.mod
│ ├── README.md USAGE.md
│ └── examples/ # optional sample data
└── my-component.wasm # built artifact (sibling)
The reference example is components/csv-groupby/. Read its Cargo.toml and wit/ for the canonical Rust pattern; the build itself is one cargo build --release --target wasm32-wasip2 command (the top-level components/Justfile owns the convention of moving the resulting .wasm to components/bin/). The example pins the wit-bindgen version explicitly in its Cargo.toml; the table above is the source of truth when starting new components.
Naming convention
- Use kebab-case for component names (
my-component).
- Cargo replaces
- with _ in produced artifacts. Build scripts use ${NAME//-/_}.wasm when copying from target/.
Choose a language
| You want… | Use | Default WASI | Notes |
|---|
| Smallest size, full WIT support, mature toolchain | Rust | 0.3 RC | 100–500 KB typical. See scripts/rust.md. |
| Rapid iteration, Python ecosystem (pure-Python deps) | Python | 0.3 RC | 5–10 MB component (embeds CPython). See scripts/python.md. |
| Web/Node integration, TypeScript types | JavaScript / TypeScript | 0.2 | 6–10 MB (embeds SpiderMonkey). See scripts/javascript.md. |
| Go ergonomics, small binaries | Go (TinyGo) | 0.2 | 0.2–1 MB. Custom WIT works but wasi:cli/command is the well-trodden path; wasi:http emerging. See scripts/go.md. |
Maturity (2026-04):
Rust ≥ Python ≥ JavaScript > Go (for components with custom WIT).
Standard workflow
- Pick a language. Open the matching cookbook in
scripts/.
- Scaffold the project (
cd components && …).
- Define the world in
wit/world.wit. If importing registry packages, run wkg wit fetch (see scripts/wkg.md).
- Implement the exports in source.
- Build to
components/bin/my-component.wasm.
- Validate:
wasm-tools validate and wasm-tools component wit to confirm the exported interface.
- Run/test with
wasmtime — defer to the wasmtime skill for invocation details (WAVE syntax, --invoke quirks, wasmtime serve for HTTP).
WIT essentials
Every language uses the same WIT in wit/world.wit. New Rust / Python
components default to WASI 0.3 RC imports:
package local:my-component;
interface api {
/// Async exports get a real `async func` — Rust generates an `async fn`,
/// Python an `async def`. Streams and futures are first-class types.
process: async func(input: string) -> result<string, string>;
}
world my-component {
import wasi:http/client@0.3.0-rc-2026-03-15;
import wasi:http/types@0.3.0-rc-2026-03-15;
export api;
}
For new JavaScript / Go components (or when targeting older runtimes),
use WASI 0.2 imports instead:
package local:my-component;
world my-component {
import wasi:cli/environment@0.2.0;
import wasi:http/outgoing-handler@0.2.0;
export run: func() -> result<_, string>;
}
When you reference packages outside your own (wasi:*, third-party),
run wkg wit fetch to populate wit/deps/ and pin versions in
wkg.lock.
Validation (quick reference)
wasm-tools validate --features all components/bin/my-component.wasm
wasm-tools component wit components/bin/my-component.wasm
ls -lh components/bin/my-component.wasm
--features all is required for any p3 component (stream<> / future<> / async func) and harmless for p2 — make it your default. If wasm-tools component wit says "not a component", you have a core module — see scripts/optimization.md for the wasm-tools component new --adapt … workaround.
Optimization, composition, packages
General troubleshooting
not a component → core module; wrap with wasm-tools component new --adapt wasi_snapshot_preview1.command.wasm.
- WIT resolution fails → run
wkg wit fetch; check ~/.config/wasm-pkg/config.toml.
- Mismatched bindings → re-generate after every
wit/ edit (per-language details in cookbooks).
- WASI 0.3 RC features unavailable → run
wasmtime 43+ with both -Sp3 and -Wcomponent-model-async, and pin WIT to 0.3.0-rc-2026-03-15. Older wasmtime (e.g. 40.x) will fail to resolve 0.3 imports; missing the -W flag will trap on stream<> / future<>. See scripts/wasi-0.3.md.
Related skills
- wasmtime — execute components with
wasmtime, invoke exports, serve HTTP. Use after building.
- component — default for the component lifecycle: build → push → pull → run, plus discovery via meta-registries.
- wasm-toolchain — raw upstream tools:
wkg for OCI push/pull with annotations and WIT-package authoring; wasm-tools for validate/embed/extract/inspect.
- just — the repo's
Justfile pins tool versions and provides install-* recipes.
When invoked
- Confirm the target language and WIT shape with the user (or infer from existing files).
- Open the matching cookbook in
scripts/.
- Scaffold or modify, build, validate.
- Hand off to wasmtime for execution; component (default) or wasm-toolchain (
wkg) for publishing.