Component Model, SIMD & Threads
The Component Model is the next evolution of WebAssembly beyond raw modules. Where a core Wasm module exposes only numeric functions, a component exposes rich typed interfaces — strings, records, lists, variants — defined in WIT (the Wasm Interface Type language). Components can be composed together at the toolchain level before deployment, enabling true language-agnostic plugin ecosystems.
WIT — Wasm Interface Types
Section titled “WIT — Wasm Interface Types”A .wit file is the contract between components. It looks like a typed IDL:
package example:greeter@0.1.0;
interface greeter { greet: func(name: string) -> string;}
world greeter-world { export greeter;}The world defines what a component exports and imports. wasm-tools (the reference toolchain) can validate, compose, and inspect components from WIT definitions.
Building a component from Rust
Section titled “Building a component from Rust”# Install cargo-component (Rust Component Model toolchain)cargo install cargo-component
# Create a new component projectcargo component new greeter --lib
# Build to a component .wasmcargo component build --release# Output: target/wasm32-wasip2/release/greeter.wasm
# Inspect the component's interfacewasm-tools component wit greeter.wasmThe wasm-tools suite handles the low-level mechanics:
# Compose two components: a greeter and a loggerwasm-tools compose greeter.wasm -d logger.wasm -o composed.wasm
# Validate a componentwasm-tools validate --features component-model greeter.wasm
# Convert a core module to a component (adapter pattern)wasm-tools component new core.wasm --adapt wasi_snapshot_preview1.wasm -o component.wasmComponent composition model
Section titled “Component composition model”flowchart LR
subgraph "Component A (Rust)"
A_wit["WIT: export greeter"]
A_core["core wasm\n(compiled Rust)"]
end
subgraph "Component B (Go)"
B_wit["WIT: import greeter\nexport http-handler"]
B_core["core wasm\n(compiled Go)"]
end
T["wasm-tools compose"]
OUT["composed.wasm\n(deployable component)"]
A_wit --> T
B_wit --> T
T --> OUT SIMD — v128 type
Section titled “SIMD — v128 type”The Fixed-Width SIMD proposal (now standardised) adds a single new value type: v128. A v128 register holds 128 bits that can be interpreted as different lane configurations:
i8x16— sixteen 8-bit integersi16x8— eight 16-bit integersi32x4— four 32-bit integersf32x4— four 32-bit floatsf64x2— two 64-bit floats
In WAT this looks like:
(module (func (export "add4f") (param $a v128) (param $b v128) (result v128) local.get $a local.get $b f32x4.add))Compilers (Rust, C/Clang) use SIMD automatically via auto-vectorisation when you enable it. You rarely write SIMD WAT by hand — it appears in compiler output for compute-heavy kernels (image processing, audio codecs, ML inference).
Threads proposal
Section titled “Threads proposal”The Threads proposal (Phase 4 — available in most browsers and runtimes) adds:
- Shared memory —
(memory (shared) N N)declares a memory that can be shared across threads. - Atomic instructions —
i32.atomic.load,i32.atomic.store,i32.atomic.rmw.addetc. waitandnotify—memory.atomic.wait32/memory.atomic.notify(Wasm equivalents offutex).
In Rust, compiling with RUSTFLAGS="-C target-feature=+atomics,+bulk-memory" and the wasm32-unknown-unknown target (with a custom allocator) enables multi-threaded Wasm. In the browser, threads require SharedArrayBuffer, which requires COOP/COEP response headers.
# Compile Rust with atomics + bulk-memory for browser threadsRUSTFLAGS="-C target-feature=+atomics,+bulk-memory" \ cargo build --target wasm32-unknown-unknown --releaseTrade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| WASI capability-based security | Much safer than the old model — a component only gets the exact capabilities the host explicitly grants | Not fully POSIX-compatible; native code that assumes ambient filesystem/network access doesn’t port into a component smoothly |
| Server-side Wasm (edge/serverless) | Microsecond-scale cold starts, a great fit for deploying components at the edge or in serverless | The ecosystem is less mature than containers — tooling around the Component Model and orchestration hasn’t been battle-tested as long |
Common mistakes
Section titled “Common mistakes”- Assuming SIMD or multi-threading work on every Wasm runtime — both are opt-in features that need a specific compile target/flag; not every runtime supports them the same way
- Overlooking how early-stage the Component Model still is — WIT interfaces can change in breaking ways between versions; committing to it in production today means being ready for that churn
- Forgetting that a component importing a WASI interface still needs an explicit capability grant from the host — successfully composing components doesn’t automatically mean access to the filesystem or network
💡 Real-world example
Fermyon Spin is built on the Component Model and Wasmtime to build and deploy serverless Wasm microservices, while Fastly Compute runs untrusted customer code as sandboxed Wasm modules with WASI-style capability control on its own edge network.