Add Road to Component Model 1.0 blog#147
Conversation
Signed-off-by: Eric Gregory <eric@cosmonic.com>
lukewagner
left a comment
There was a problem hiding this comment.
(Sorry for the slow review! I started reading, then got distracted, then forgot.) This looks like a great summary to me; thanks so much for writing it up!
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Co-authored-by: Luke Wagner <mail@lukewagner.name>
Signed-off-by: Eric Gregory <eric@cosmonic.com>
Signed-off-by: Eric Gregory <eric@cosmonic.com>
tschneidereit
left a comment
There was a problem hiding this comment.
This is a really excellent post!
I left a bunch of feedback and suggestions, but none of that changes anything major. The part of the feedback I care about most is the mention of simplifications to the spec between P3 and 1.0. And on that, it'd be nice to integrate a description of the parallel tracks approach, where for a while P3.x and 1.0-pre will co-exist, with changes landing on both, and 1.0-pre always staying a subset of P3.x. I wasn't quite sure where that'd make most sense, though.
The other general bit I think would be nice is to add links to a lot more things. Certainly mentions of projects, such as jco and Gravity. But also recordings of the various Summit presentations mentioned throughout, and ideally also issues/PRs for the changes mentioned, where those already exist.
| --- | ||
| WASI P3 is almost here, bringing native async support to the **WebAssembly System Interface (WASI)** and **Component Model**. In this post, we're looking to the *next* big milestone: a stable, formally specified Component Model 1.0. | ||
|
|
||
| At February's Bytecode Alliance Plumbers Summit, Luke Wagner and Alex Crichton gave a preview of what the path to a stable 1.0 actually looks like. Last month at [Wasm I/O 2026 in Barcelona](https://wasm.io/), Wagner [expanded on that vision](https://youtu.be/qq0Auw01tH8?si=4Zb2r52SNsAsUtkQ). So let's take a look at where the Component Model is heading. |
There was a problem hiding this comment.
| At February's Bytecode Alliance Plumbers Summit, Luke Wagner and Alex Crichton gave a preview of what the path to a stable 1.0 actually looks like. Last month at [Wasm I/O 2026 in Barcelona](https://wasm.io/), Wagner [expanded on that vision](https://youtu.be/qq0Auw01tH8?si=4Zb2r52SNsAsUtkQ). So let's take a look at where the Component Model is heading. | |
| At February's Bytecode Alliance Plumbers Summit, Luke Wagner and Alex Crichton gave a preview of what the path to a stable 1.0 actually looks like. At [Wasm I/O 2026 in Barcelona](https://wasm.io/) in March, Wagner [expanded on that vision](https://youtu.be/qq0Auw01tH8?si=4Zb2r52SNsAsUtkQ). So let's take a look at where the Component Model is heading. |
| --- | ||
| title: "The Road to Component Model 1.0" | ||
| author: "Eric Gregory" | ||
| date: "2026-04-21" |
There was a problem hiding this comment.
Let's update this once we know a release date (hopefully Real Soon Now!)
| --- | ||
| WASI P3 is almost here, bringing native async support to the **WebAssembly System Interface (WASI)** and **Component Model**. In this post, we're looking to the *next* big milestone: a stable, formally specified Component Model 1.0. | ||
|
|
||
| At February's Bytecode Alliance Plumbers Summit, Luke Wagner and Alex Crichton gave a preview of what the path to a stable 1.0 actually looks like. Last month at [Wasm I/O 2026 in Barcelona](https://wasm.io/), Wagner [expanded on that vision](https://youtu.be/qq0Auw01tH8?si=4Zb2r52SNsAsUtkQ). So let's take a look at where the Component Model is heading. |
There was a problem hiding this comment.
Here and everywhere else below, I think it'd fit the tone of our blog a bit better to use first instead of last names
|
|
||
| At the Plumbers Summit, Wagner described the relationship between the Component Model and WASI as analogous to a microkernel architecture: the Component Model is the always-present microkernel, providing foundational primitives that run across any host. WASI layers on top like OS services (e.g., networking, storage, graphics) that run as processes on top of the microkernel and may or may not be present on a given device. A browser, for instance, has very strong opinions about what I/O APIs exist; WASI interfaces run there via polyfill. But the Component Model itself can be implemented natively in the browser alongside core WebAssembly, since it only provides computational primitives, not I/O. | ||
|
|
||
| In practical terms, the Component Model is already stable. P1 modules still work. P2 components still work. The team has been maintaining this stability since P1 using semantic versioning, side-by-side implementations, and Wasm-to-Wasm adapters. That story continues past 1.0. As Wagner put it: "We can start using this stuff now." But *getting* to Component Model 1.0 involves critical work across several important areas. |
There was a problem hiding this comment.
Slightly reworded to also include WASI, because otherwise the mention of (pre-CM) P1 feels a bit off. Plus, it seems important to highlight that all this applies to WASI as well.
| In practical terms, the Component Model is already stable. P1 modules still work. P2 components still work. The team has been maintaining this stability since P1 using semantic versioning, side-by-side implementations, and Wasm-to-Wasm adapters. That story continues past 1.0. As Wagner put it: "We can start using this stuff now." But *getting* to Component Model 1.0 involves critical work across several important areas. | |
| In practical terms, both WASI and the Component Model are already heavily used in production. Despite ongoing evolution of both the binary format and WASI APIs, platform providers and embedders can give strong backwards-compatibility guarantees. P1 modules still work. P2 components still work. The team has been maintaining this stability since P1 using semantic versioning, side-by-side implementations, and Wasm-to-Wasm adapters. That story continues past 1.0. As Wagner put it: "We can start using this stuff now." But *getting* to Component Model 1.0 involves critical work across several important areas. |
There was a problem hiding this comment.
Note that I didn't change the mention of Wagner in here, since that suggestion from above might be rejected.
|
|
||
| ### 1. ABI improvements | ||
|
|
||
| The Component Model's current Application Binary Interface (ABI), the calling convention that governs how components pass data to each other, relies on a function conventionally called `cabi_realloc`. When a callee returns a value like a list of strings, the host calls `cabi_realloc` to allocate memory for each element, then copies everything before returning to the caller. This works, but experience has surfaced real friction: heap fragmentation over time, difficulty handling large allocation failures gracefully, one host-to-guest call per value in a list, and trouble using custom memory allocators. |
There was a problem hiding this comment.
| The Component Model's current Application Binary Interface (ABI), the calling convention that governs how components pass data to each other, relies on a function conventionally called `cabi_realloc`. When a callee returns a value like a list of strings, the host calls `cabi_realloc` to allocate memory for each element, then copies everything before returning to the caller. This works, but experience has surfaced real friction: heap fragmentation over time, difficulty handling large allocation failures gracefully, one host-to-guest call per value in a list, and trouble using custom memory allocators. | |
| The Component Model's current Application Binary Interface (ABI), the calling convention that governs how components pass data to each other, relies on a function conventionally called `cabi_realloc`, which all components are required to export. When a callee returns a value like a list of strings, the host calls the calling component's `cabi_realloc` to allocate memory for each element, then copies everything before returning to the caller. This works, but experience has surfaced real friction: heap fragmentation over time, difficulty handling large allocation failures gracefully, one host-to-guest call per value in a list, and trouble using custom memory allocators. |
|
|
||
| Bundled into the same transition are multivalue returns (using Wasm multivalue for return types at the C ABI level) and an error context value in every result's error case, so there's always a standard way for hosts to attach backtraces and debug information. | ||
|
|
||
| There is one significant dependency: LLVM doesn't yet support multivalue at the C ABI level. Getting that upstream may be the longest lead time in this piece of work. |
There was a problem hiding this comment.
Hot off the presses:
| There is one significant dependency: LLVM doesn't yet support multivalue at the C ABI level. Getting that upstream may be the longest lead time in this piece of work. | |
| There is one significant dependency: LLVM doesn't yet support multivalue at the C ABI level. A [proposal for the precise ABI](https://github.com/WebAssembly/tool-conventions/pull/268) exists, but getting that upstream may be the longest lead time in this piece of work. |
|
|
||
| There's also a separate GC ABI option planned, enabling components to pass values via Wasm GC-allocated memory instead of linear memory, and avoiding copies through linear memory for GC-based languages. Nick Fitzgerald has a pre-proposal on this in [Component Model issue 525](https://github.com/WebAssembly/component-model/issues/525). | ||
|
|
||
| Sitting alongside the ABI work is a related performance goal: zero overhead on synchronous calls between components. The current implementation manages async task infrastructure across component boundaries via a host call, which (per Nick Fitzgerald's Plumbers Summit measurements) adds roughly 3.5x overhead even on purely synchronous call paths. Some of this has already been addressed at the spec level (the recursion check was removed during P3 development). The remaining work is [planned](https://github.com/bytecodealliance/wasmtime/issues/12311) for after WASI P3 ships, refactoring task state so synchronous adapters allocate a lightweight task on the stack that [Cranelift](https://github.com/bytecodealliance/wasmtime/tree/main/cranelift) (Wasmtime's optimizing code generation backend) can largely optimize away. The goal is to restore the performance profile that synchronous adapters had before component model async support was added. |
There was a problem hiding this comment.
| Sitting alongside the ABI work is a related performance goal: zero overhead on synchronous calls between components. The current implementation manages async task infrastructure across component boundaries via a host call, which (per Nick Fitzgerald's Plumbers Summit measurements) adds roughly 3.5x overhead even on purely synchronous call paths. Some of this has already been addressed at the spec level (the recursion check was removed during P3 development). The remaining work is [planned](https://github.com/bytecodealliance/wasmtime/issues/12311) for after WASI P3 ships, refactoring task state so synchronous adapters allocate a lightweight task on the stack that [Cranelift](https://github.com/bytecodealliance/wasmtime/tree/main/cranelift) (Wasmtime's optimizing code generation backend) can largely optimize away. The goal is to restore the performance profile that synchronous adapters had before component model async support was added. | |
| Sitting alongside the ABI work is a related performance goal: zero overhead on synchronous calls between components. The current implementation manages async task infrastructure across component boundaries via a host call, which (per Nick Fitzgerald's Plumbers Summit measurements) adds roughly 3.5x overhead even on purely synchronous call paths. Some of this has already been addressed at the spec level (the recursion check was removed during P3 development). The remaining work is [planned](https://github.com/bytecodealliance/wasmtime/issues/12311) for after WASI P3 ships, refactoring task state so synchronous adapters allocate a lightweight task on the stack that compilers like [Cranelift](https://github.com/bytecodealliance/wasmtime/tree/main/cranelift) (Wasmtime's optimizing code generation backend) can largely optimize away. The goal is to restore the performance profile that synchronous adapters had before component model async support was added. |
|
|
||
| ### 3. Making the Component Model easier to implement | ||
|
|
||
| Getting native browser support requires a manageable implementation burden. The plan here is a pair of C ABIs, one for guests and one for hosts, both expressed as header files generated by `wit-bindgen`. |
There was a problem hiding this comment.
I added language here on what I think is a very important additional aspect of making implementation easier: the planned simplification of the spec.
| Getting native browser support requires a manageable implementation burden. The plan here is a pair of C ABIs, one for guests and one for hosts, both expressed as header files generated by `wit-bindgen`. | |
| Getting native browser support requires a manageable implementation burden. The plan here has two key components: | |
| The first one is to simplify the specification itself. The Component Model 1.0 spec will only include the "good parts" of the P3 spec, instead of being a superset of what exists right now. Most importantly, the ABI change described above means that implementers aiming for 1.0, but not P3, support don't have to support the current, `cabi_realloc` based calling convention. As is the case for P1 and P2 support in various production environments today, existing P3 components will still be supported with the help of tools and adapters. | |
| The second one is a pair of C ABIs to ease implementation, one for guests and one for hosts, both expressed as header files generated by `wit-bindgen`. |
|
|
||
| Sy Brand presented a deep dive on cooperative threads at the Plumbers Summit, and it's worth noting here that they're implemented at the Component Model level, below the WASI layer. A Rust component using `std::thread::spawn` gets cooperative thread support when it lands, with nothing special needed in WIT. | ||
|
|
||
| The implementation is in progress: `wasi-libc` pthreads support is largely done, LLVM patches are under review, and Wasmtime has a functional implementation under a feature flag. Cooperative threads support will ship in a follow-up WASI P3 minor release. These advancements also pave the road for shared-everything threads later, since many of the heaviest toolchain lifts for cooperative threads carry over directly. |
There was a problem hiding this comment.
| The implementation is in progress: `wasi-libc` pthreads support is largely done, LLVM patches are under review, and Wasmtime has a functional implementation under a feature flag. Cooperative threads support will ship in a follow-up WASI P3 minor release. These advancements also pave the road for shared-everything threads later, since many of the heaviest toolchain lifts for cooperative threads carry over directly. | |
| The implementation is in progress: `wasi-libc` pthreads support is largely done, LLVM patches have just landed and will be included in the next release, and Wasmtime has a functional implementation under a feature flag. Cooperative threads support will ship in a follow-up WASI P3 minor release. These advancements also pave the road for shared-everything threads later, since many of the heaviest toolchain lifts for cooperative threads carry over directly. |
|
|
||
| The implementation is in progress: `wasi-libc` pthreads support is largely done, LLVM patches are under review, and Wasmtime has a functional implementation under a feature flag. Cooperative threads support will ship in a follow-up WASI P3 minor release. These advancements also pave the road for shared-everything threads later, since many of the heaviest toolchain lifts for cooperative threads carry over directly. | ||
|
|
||
| Also shipping in an early WASI P3 follow-up release is **stream splicing**, the ability to splice one stream directly into another without an intermediate copy. Stream splicing is important for streaming performance, since unnecessary copying through an intermediate buffer is costly on hot paths, and was simply too close to the wire to make WASI P3 itself. |
There was a problem hiding this comment.
| Also shipping in an early WASI P3 follow-up release is **stream splicing**, the ability to splice one stream directly into another without an intermediate copy. Stream splicing is important for streaming performance, since unnecessary copying through an intermediate buffer is costly on hot paths, and was simply too close to the wire to make WASI P3 itself. | |
| Also shipping in an early WASI P3 follow-up release will be **stream splicing**, the ability to splice one stream directly into another without an intermediate copy. Stream splicing is important for streaming performance, since unnecessary copying through an intermediate buffer is costly on hot paths, and was simply too close to the wire to make WASI P3 itself. |
This PR adds a blog outlining the path to Component Model 1.0, based on presentations from the Plumbers Summit and WASM.io.