Skip to main content

WebAssembly Serverless Architecture 2026: WASI Preview 2, Component Model, and Edge Deployment

Created: March 16, 2026 Larry Qu 5 min read

Introduction

WebAssembly (Wasm) has evolved from a browser-only technology into a universal runtime for serverless computing. The key developments in 2026 — WASI Preview 2 reaching production stability, the Component Model enabling cross-language module composition, and Wasm runtimes achieving sub-millisecond cold starts — have made Wasm a practical alternative to containers for edge functions, microservices, and AI inference at the edge.

This guide covers the WASI system interface, the Component Model for polyglot programming, the major serverless frameworks (Spin 3.0, wasmCloud), Rust code examples for building Wasm HTTP services, and deployment patterns for edge and cloud environments.

WASI: The System Interface for Wasm

WASI (WebAssembly System Interface) provides standardized APIs for Wasm modules to interact with the operating system — files, network sockets, HTTP, clocks, random numbers. WASI Preview 2 reached production stability in 2025-2026, and WASI Preview 3 (0.3.0, February 2026) added native async I/O support with a futures-and-streams model.

flowchart LR
    subgraph WasmModule["Wasm Component<br/>(Rust, Go, C++)"]
        A[Application Code]
    end

    subgraph WASI["WASI Preview 2 APIs"]
        FS[wasi:filesystem<br/>File I/O]
        SOCK[wasi:sockets<br/>TCP/UDP]
        HTTP[wasi:http<br/>HTTP requests]
        CLI[wasi:cli<br/>Args, env, stdio]
        RAND[wasi:random<br/>Secure random]
        CLOCK[wasi:clocks<br/>Monotonic + wall clock]
    end

    subgraph Runtime["Wasm Runtime<br/>Wasmtime / WasmEdge / Wasmer"]
        RT[Execution Engine]
    end

    subgraph Host["Host OS"]
        OS[Linux / Windows / macOS Kernel]
    end

    A <--> WASI
    WASI <--> RT
    RT <--> OS

WASI Preview 2 provides capability-based security — each API must be explicitly granted to the module. A module that only needs HTTP cannot access the filesystem unless wasi:filesystem is in its allowlist. This is a stronger security model than containers, where any process in the container can access all container resources.

WASI Preview 2 vs Preview 3

Feature Preview 2 (stable) Preview 3 (0.3.0, Feb 2026)
I/O Model Blocking Async (futures + streams)
HTTP Client + Server Client + Server (improved)
Networking TCP, UDP TCP, UDP, QUIC
Component Model Yes Yes (enhanced)
Production ready Yes Early adopter
Runtime support Wasmtime 22+ Wasmtime 44+

Component Model: Polyglot Programming

The Component Model lets Wasm modules written in different languages (Rust, Go, Python, C++) interoperate seamlessly through a shared type system. WIT (Wasm Interface Types) defines the interfaces, and wit-bindgen generates language-specific bindings.

WIT Interface Definition

// hello.wit — define a component interface
package example:hello;

interface hello-world {
    greet: func(name: string) -> string;
}

world hello-world-server {
    import hello-world;
    export wasi:http/handler;
}

Rust HTTP Component (using WASI Preview 2)

// Cargo.toml
// [dependencies]
// wasi = "0.13"
// wasi-http = "0.4"

use wasi::http::incoming_handler;
use wasi::http::types::{
    IncomingRequest, ResponseOutparam, OutgoingResponse,
    OutgoingBody, Headers, Method,
};

struct MyServer;

impl incoming_handler::Guest for MyServer {
    fn handle(request: IncomingRequest, response_out: ResponseOutparam) {
        let path = request.path_with_query().unwrap_or_default();
        let method = request.method();

        let (status, body_text) = match (method, path.as_str()) {
            (Method::Get, "/") => (200, "Hello from Wasm!".to_string()),
            (Method::Get, "/health") => {
                (200, r#"{"status": "healthy", "version": "1.0.0"}"#.into())
            }
            (Method::Post, "/echo") => {
                // Read request body (blocking read up to 1MB)
                let body = request.consume().unwrap();
                let stream = body.stream().unwrap();
                let data = stream.blocking_read(1024 * 1024).unwrap();
                let text = String::from_utf8_lossy(&data).to_string();
                (200, text)
            }
            _ => (404, "Not Found".to_string()),
        };

        // Build the response
        let headers = Headers::new();
        let response = OutgoingResponse::new(status, &headers);
        let body = response.body().unwrap();
        body.stream().unwrap().blocking_write(body_text.as_bytes()).unwrap();
        body.finish().unwrap();
        ResponseOutparam::set(response_out, Ok(response));
    }
}

// Required for the component model entry point
wasi::http::incoming_handler::export!(MyServer);

Compile with:

cargo build --target wasm32-wasip2 --release

The output .wasm file can run on any WASI Preview 2-compatible runtime: Wasmtime v44+, Spin 3.0+, or wasmCloud.

Serverless Frameworks

Wasmtime v44.0.0 (April 2026)

The reference Wasm runtime with full WASI Preview 2 support:

# Install Wasmtime
curl -fsSL https://wasmtime.dev/install.sh | bash

# Run a Wasm HTTP component
wasmtime serve my-component.wasm --addr 0.0.0.0:8080

# Test the endpoint
curl http://localhost:8080/health
# {"status": "healthy", "version": "1.0.0"}

Fermyon Spin 3.0 (GA, 2026)

Spin is a framework for building event-driven microservices with Wasm components. Version 3.0 uses the Component Model natively:

# Install Spin
curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash

# Create a new Spin application
spin new my-app --template http-rust
cd my-app

# Build and deploy
spin build
spin deploy  # to Fermyon Cloud or self-hosted
# spin.toml — Spin 3.0 application manifest
spin_manifest_version = "3"
name = "api-gateway"
version = "1.0.0"

[[trigger.http]]
route = "/api/..."
component = "router"

[component.router]
source = "target/wasm32-wasip2/release/router.wasm"
# WASI capabilities are declared explicitly
[component.router.wasi]
filesystem = { directories = ["/data"] }
http = true

wasmCloud (CNCF Incubation)

wasmCloud provides an actor-based platform for distributed Wasm applications with capability-based security:

# Start a wasmCloud host
wasmcloud_host

# Deploy a component via wash CLI
wash app deploy my-app.wadm.yaml
# wadm.yaml — wasmCloud application definition
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: edge-gateway
spec:
  components:
    - name: http-handler
      type: actor
      properties:
        image: ghcr.io/myorg/http-handler:v1
      traits:
        - type: spreadscaler
          properties:
            spread: [{requirements: {"zone": "us-east"}, weight: 1}]
        - type: link
          properties:
            target: keyvalue-store
            namespace: wasi
            package: keyvalue

Performance Comparison

Metric Container (Docker) Wasm (Wasmtime) AWS Lambda (container)
Cold start 100ms - 5s 1-5ms 100ms - 2s
Warm start 1-5ms 1-50µs 1-5ms
Memory overhead 50-500MB 1-10MB 50-100MB
Binary size 10-100MB+ 0.1-5MB 10-100MB
Throughput (HTTP) ~15K req/s ~50K req/s ~10K req/s

Wasm’s sub-millisecond cold start eliminates the need for warm pools in serverless deployments. Combined with 10-50x smaller memory footprint, a single host can run thousands of Wasm components where it could run tens of containers.

Edge Deployment Pattern

flowchart TD
    CDN[CDN / Edge Gateway] -->|Route by path| R{Router}

    R -->|/api/auth| Auth[Auth Component<br/>Rust, 0.5ms startup]
    R -->|/api/users| Users[User API Component<br/>Go, 0.3ms startup]
    R -->|/api/search| Search[Search Component<br/>Python, 1.2ms startup]

    Auth --> KV[(Key-Value Store<br/>Redis)]
    Users --> PG[(PostgreSQL)]
    Search --> ES[(Elasticsearch)]

    Auth -->|WASI HTTP| Users
    Users -->|Component link| Search

Each component is an independent Wasm module with explicit capability declarations. The edge router starts components on demand in 1-5ms and caches them for subsequent requests. Components can call each other through WASI HTTP or component model linking.

Resources

Comments

👍 Was this article helpful?