WebAssembly

Two targets and one browser workflow.

WASI

A wasm32-wasi-musl executable, validated as a real WebAssembly binary:

ZAZA_EXAMPLES=wasm-wasi zig build wasm-wasi
ZAZA_EXAMPLES=wasm-wasi zig build wasm-wasi-report
wasm wasi valid

The artifact is zig-out/bin/wasm_wasi_demo.wasm, runnable under any WASI runtime. The report step uses Node's WebAssembly.validate.

Freestanding exports

A module with no entry point that exports functions for a host to call:

const target = b.resolveTargetQuery(.{
    .cpu_arch = .wasm32,
    .os_tag = .freestanding,
});
// ...
exe.entry = .disabled;
exe.rdynamic = true;
ZAZA_EXAMPLES=wasm-exports zig build wasm-exports-run
wasm add: 42
wasm mul_add: 42

The run step instantiates the module in Node and calls two exports.

Browser

The same .wasm staged into a servable directory alongside an HTML page and a JS loader:

ZAZA_EXAMPLES=wasm-exports zig build wasm-web-demo        # stage
ZAZA_EXAMPLES=wasm-exports zig build wasm-web-demo-smoke  # verify over HTTP
ZAZA_EXAMPLES=wasm-exports zig build wasm-web-demo-serve  # serve

Everything lands under zig-out/www/wasm-exports/.

wasm-web-demo-smoke starts the server on port 8123, requests /index.html, /app.js, and /wasm_exports_demo.wasm, then exits:

Serving zig-out/www/wasm-exports at http://127.0.0.1:8123

wasm-web-demo-serve binds http://127.0.0.1:8000 and runs until interrupted. The server is build_lib/static_server.zig, built as part of the graph, so there is no external dependency for local serving.