WASI preview 3: adoption and real cases

Logotipo horizontal oficial de Spin, el framework de aplicaciones basadas en componentes WebAssembly desarrollado por Fermyon y graduado en la CNCF, que ha sido uno de los primeros entornos en producción con soporte completo para WASI preview 3 incluyendo async nativo, streams bidireccionales y el modelo de componentes estabilizado a finales de 2025

WASI preview 3 was officially stabilized in late 2025, after more than two years of work on the foundations preview 2 left in 2024. Getting here has cost more than the community expected, and for a time it seemed the project was stuck in debates about async and component model. Starting 2026 with a published standard and several runtimes with solid support, time to evaluate what has changed in practice and what real cases have started moving.

What preview 3 brings that preview 2 missed

Preview 2 was already a perfectly usable standard for many cases. It provided interfaces for filesystem, networking, randomness, clock, and environment, all over the component model introduced in 2024. But there were three gaps limiting adoption in advanced scenarios: absence of native async, lack of well-defined bidirectional streams, and limitations in interaction between concurrent components.

Preview 3 resolves these three gaps in coordinated fashion. The async model is now part of the standard itself, with primitives for futures, streams, and cancellation fitting naturally in the component model. Bidirectional streams allow portably implementing protocols like WebSocket, gRPC, or any continuous client-server communication. And concurrency between components is specified in enough detail to build real architectures where several components collaborate via async messages.

The most important practical change is you no longer have to choose between portability and async. Until 2025, cases needing serious concurrency ended up either outside WASI with proprietary runtimes, or with ad-hoc solutions that broke compatibility between runtimes. With preview 3, a component using async runs on wasmtime, WasmEdge, JCO (for browser), and main commercial runtimes without changes, as long as they’ve upgraded to preview 3, which most have done during Q1 2026.

Mature runtimes and production cases

Wasmtime, the reference runtime maintained by Bytecode Alliance, achieved full preview 3 support with its version 26, released in November 2025. WasmEdge followed in January 2026 with its version 0.15. Spin from Fermyon incorporated preview 3 in its version 3.5, published in early year. These three bases cover most real cases I see in production today.

A concrete case I’ve seen work very well is custom API gateway with Spin 3.5. A company that needed complex routing logic, request transformation, and specific authorization policies has replaced their prior NGINX-with-Lua-scripts gateway with a set of Wasm components in Spin. The main reason for the change wasn’t performance (NGINX was enough) but maintainability: Wasm components can be written in Rust, TypeScript, or Go with your preferred model, tested in isolation, versioned independently, and deployed without restarting the main process. Preview 3 was needed because more complex policies required async calls to external services during authorization evaluation.

Another practical case is extension plugins for SaaS applications. Several products historically allowing JavaScript sandbox extensions have moved their architecture to WebAssembly components. The practical reason is Wasm plugins are faster, safer (native runtime sandbox), and portable between languages. Preview 3 has been key here because many plugins need to make HTTP calls or access internal product APIs with async patterns, and preview 2 forced clumsy workarounds or blocking functions that degraded performance.

The component and library ecosystem

Beyond the standard, the precompiled component ecosystem has enriched notably. WASI Cloud, the family of standardized interfaces for cloud services (queues, blobs, KV, pub/sub, LLM), has stabilized its first official version with preview 3 integrated. This allows building applications portable between providers: the same Wasm component speaking WASI Cloud works over AWS, Azure, Google Cloud, or a self-hosted backend, just by changing the adapter. The real portability Kubernetes promised but never fully delivered starts to be visible at this level.

Build tools have also improved. Cargo component (for Rust), jco (for JavaScript and TypeScript), and the Go ecosystem with tinygo or the official WebAssembly compiler produce preview 3 components with mature tooling, decent errors, and documentation that’s no longer just the repo README. Tooling has reached a level that was poor a year ago and now allows real productivity.

Reusable component libraries are the next step. Standard components already exist for JSON parsing, HTTP client, Postgres client, Protobuf serialization, libsodium encryption, and many more. Composing them inside an application is as simple as declaring dependencies in the manifest and letting the linker resolve composition. This model allows reusing logic between languages naturally; a component compiled from Rust is consumed without friction by a component written in TypeScript, no FFI.

A minimal example with Spin and async

A common 2026 pattern is a small web API consuming external services with concurrency. The following fragment shows how it looks in Spin 3.5 with Rust and WASI preview 3:

use spin_sdk::http::{Method, Request, Response, Router};
use spin_sdk::http_component;
use futures::future::join_all;

#[http_component]
async fn handle_request(req: Request) -> anyhow::Result<Response> {
    let urls = vec![
        "https://api.one.example/status",
        "https://api.two.example/status",
        "https://api.three.example/status",
    ];

    let fetches = urls.iter().map(|u|
        spin_sdk::http::send::<_, Response>(Request::new(Method::Get, u)));

    let results = join_all(fetches).await;
    let healthy = results.iter().filter(|r| r.is_ok()).count();

    Ok(Response::new(200, format!("{} of {} healthy", healthy, urls.len())))
}

The above fragment would have been impossible in preview 2 without tricks outside the spec. In preview 3 it’s natural syntax, with real concurrency between HTTP requests, and runs on any compatible runtime without specific code. This ergonomics is what has unlocked cases that had been waiting two years.

Where there’s still friction

Not all is rosy. Preview 3 support in commercial runtimes beyond those mentioned remains uneven. Some edge-computing providers that adopted preview 2 early are taking longer than expected to migrate to preview 3, forcing compilation for the older version if you want maximum portability. Most will stabilize during H1 2026, but today it’s still real friction.

Cold-start times remain worse than native binaries. For loads requiring very low latency on pointwise invocations, Wasm still adds a few milliseconds in runtime startup and component validation. For long-running loads this doesn’t matter, but for microservices invoked thousands of times per minute with aggressive latency SLOs, you have to measure.

Debugging remains clumsier than native binaries. Wasm component stack traces are less readable, visual debuggers are more limited, and low-level instrumentation (profiling, tracing) requires more effort. There’s continuous progress but diagnostic tooling trails any mature native language.

When adopting now pays

For a team considering Wasm in production in 2026, my recommendation is distinguishing three scenarios. First, cases where Wasm brings clear, non-urgent value: plugins for SaaS products, edge-computing functions, logic embedded in larger applications. Here it pays to start now with preview 3, knowing the initial curve is notable but mid-term return is solid.

Second, cases of replacing working existing architectures. If you have Docker containers with healthy microservices, replacing them with Wasm components rarely pays, though technically possible. Migration cost and retraining the team usually exceeds density or startup-time gains. Change only if there’s a concrete operational reason.

Third, cases where Wasm’s promise (extreme portability, strong isolation, density) solves a real problem you have. Teams needing to deploy the same logic on server, edge, and browser without rewriting, teams wanting to run third-party code with isolation guarantees, teams operating at scales where per-machine density matters a lot. Here Wasm with preview 3 is the most solid technical option of 2026 and adopting is a sound strategic decision.

When it pays

The honest reading of preview 3 in early 2026 is that WebAssembly has finally reached the maturity it promised since 2019. Preview 2 already allowed interesting cases, but preview 3 closes the circle with async, streams, and concurrent composition. The ecosystem is starting to really bloom, with mature runtimes, reusable libraries, and demonstrable production cases. It’s not a universal replacement for containers or proprietary serverless functions, and you don’t need to adopt it everywhere. But for the niches where its advantages are real, 2026 is the year to stop waiting and start using it, with the expectation that the standard is stable, runtimes are compatible, and tooling allows genuine productivity.

Entradas relacionadas