Skip to content

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.

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.

Terminal window
# Install cargo-component (Rust Component Model toolchain)
cargo install cargo-component
# Create a new component project
cargo component new greeter --lib
# Build to a component .wasm
cargo component build --release
# Output: target/wasm32-wasip2/release/greeter.wasm
# Inspect the component's interface
wasm-tools component wit greeter.wasm

The wasm-tools suite handles the low-level mechanics:

Terminal window
# Compose two components: a greeter and a logger
wasm-tools compose greeter.wasm -d logger.wasm -o composed.wasm
# Validate a component
wasm-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.wasm
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
Two components composed into one deployable artifact

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 integers
  • i16x8 — eight 16-bit integers
  • i32x4 — four 32-bit integers
  • f32x4 — four 32-bit floats
  • f64x2 — 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).

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 instructionsi32.atomic.load, i32.atomic.store, i32.atomic.rmw.add etc.
  • wait and notifymemory.atomic.wait32 / memory.atomic.notify (Wasm equivalents of futex).

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.

Terminal window
# Compile Rust with atomics + bulk-memory for browser threads
RUSTFLAGS="-C target-feature=+atomics,+bulk-memory" \
cargo build --target wasm32-unknown-unknown --release
What language is used to define Component Model interface contracts?
What is the single new value type introduced by the SIMD proposal?
Which tool composes two Wasm components into one deployable artifact?
What browser security headers are required to use SharedArrayBuffer for Wasm threads?