Skip to content
Blog

WASI Preview 2: Running WebAssembly Outside the Browser

How WASI 0.2 rebuilt WebAssembly on the Component Model, what Preview 3 adds with native async, and how to build and run a component today with Rust and Wasmtime.

Published on • October 9, 2026

AI Assistant

WebAssembly escaped the browser years ago, but “running Wasm on a server” was long synonymous with the original syscall-style interface called WASI Preview 1. WASI Preview 2 — formally WASI 0.2 — rebuilt that interface from scratch on the Component Model, and it changes what a Wasm module can be: a portable, language-agnostic component with typed imports and exports.

Here is the landscape in 2026, and how to build against it.

Modules vs. components: the core distinction

  • A module is core Wasm. It can only target WASI 0.1 — the snapshot-preview1 syscall interface.
  • A component targets the Component Model and gets WASI 0.2 (and 0.3) — composability, cross-language linking, and rich interface types defined in WIT (Wasm Interface Types).

Capability security comes from worlds: notably wasi:cli/command for command-line programs and wasi:http/proxy for HTTP client/server capability (built atop wasi:io). No ambient authority — a component can only do what its world imports.

The milestone map

MilestonePreviewStatus
WASI 0.1Preview 1Modules; most widely supported across runtimes
WASI 0.2Preview 2Components + Component Model; production target today
WASI 0.3Preview 3Native async (stream<T>, future<T>, subscriptions); Wasmtime 46 runs it by default

WASI 0.3 is the current stable milestone — but ecosystem support is uneven, so 0.2 is still the pragmatic target for most work.

Building a component with Rust

Rust is the furthest along: wasm32-wasip2 is Tier 2 on stable, supporting both modules and components on 0.1/0.2:

rustup target add wasm32-wasip2
cargo build --release --target wasm32-wasip2
wasmtime run target/wasm32-wasip2/release/app.wasm

For 0.3, wasm32-wasip3 is Tier 3 and nightly-only; the wasip3 crate provides 0.3 bindings usable from wasip2 (though std on wasip2 remains 0.2).

Wrapping a legacy module

Existing core Wasm modules (the typical path for C/C++) get upgraded to components with wasm-tools plus a 0.1→0.2 adapter:

wasm-tools component new app.wasm -o app.wasm \
  --adapt wasi_snapshot_preview1=preview1.wasm

WIT: the interface language

Components describe their imports and exports in WIT:

package example:app;

world hello {
  import wasi:io/streams@0.3.0;
  export run: func();
}

That @0.3.0 matters — see gotchas below.

Language support snapshot

  • Rust: wasm32-wasip2 Tier 2 stable; wasm32-wasip3 Tier 3 nightly
  • Go: upstream GOOS=wasip1 is stuck at 0.1 modules; components via bytecodealliance/go-modules or TinyGo
  • C/C++: wasi-sdk for 0.1/0.2 (0.3 toolchain not yet shipped); components via wasm-tools
  • Python: componentize-py produces 0.2 components
  • JS/TS: jco for 0.2; 0.3 is experimental via @bytecodealliance/preview3-shim
  • Kotlin, MoonBit, Ruby, C# (componentize-dotnet): in various states of 0.2 support
  • Zig: 0.1 modules only; Java/Swift planned

Gotchas

  • You must pick a milestone deliberately. Mixing a 0.1 module world with 0.2 expectations means adapters. Legacy toolchains bridge with wasm-tools component new.
  • Version pinning bites. Canonical interface names exist, but not all tools do version-aware linking yet — mismatched WIT versions surface as confusing wrong type errors at instantiation. Pin 0.3.0 uniformly across WIT-aware tools.
  • 0.3 is still landing. Rust bindings are nightly Tier 3, the jco shim is experimental, and C/Kotlin toolchains have not shipped it. For anything non-Rust today, target 0.2.
  • Go’s upstream path is 0.1 — component support lives in out-of-tree tooling.

Why it matters

The practical payoff of Preview 2 is that a Wasm component becomes a dependency, not just a program: a Rust inference engine, a Python transform, and a JS host can link through shared WIT interfaces with capability-based sandboxing. For AI infrastructure specifically — sandboxed tool execution, portable edge functions, plugin systems — the Component Model is the isolation primitive Wasm was missing in the browser-only era.

Wrapping up

WASI 0.2 moved the ecosystem from syscall snapshots to typed components, and 0.3 is adding the async story that server runtimes need. If you are starting today: build with wasm32-wasip2 on stable Rust, run on Wasmtime, pin your WIT versions, and treat 0.3 as a preview unless you are on nightly. The browser was only ever step one for WebAssembly.

References