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 --release