Skip to content

Add Async, Streams, and Futures concepts page and Migrating from WASI P2 to WASI P3 guide#352

Open
ericgregory wants to merge 6 commits into
bytecodealliance:mainfrom
ericgregory:p3-migrating-to-p3
Open

Add Async, Streams, and Futures concepts page and Migrating from WASI P2 to WASI P3 guide#352
ericgregory wants to merge 6 commits into
bytecodealliance:mainfrom
ericgregory:p3-migrating-to-p3

Conversation

@ericgregory

@ericgregory ericgregory commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Adds two new pages under Understanding: design/async.md introduces the Canonical ABI primitives (async func, stream<T>, future<T>) added for WASI P3, and design/migrating-to-p3.md covers the P2-to-P3 concept mapping for component authors with before/after WIT examples, per-interface notes, and tooling requirements.

Add a new design/async.md introducing the Canonical ABI primitives
(`async func`, `stream<T>`, `future<T>`) that the Component Model added
for the WASI P3 release. The page covers the sandwich problem (why
native async matters for composition), each primitive with a worked WIT
example, the stream-plus-future and write-direction-flip patterns, and a
tooling-support pointer.

Hook the page into Component Model Concepts as a new subsection after
Packages, and add the SUMMARY.md entry under that umbrella.

Signed-off-by: Eric Gregory <eric@cosmonic.com>
Add a new design/migrating-to-p3.md covering the conceptual P2 -> P3
mapping for component authors: a "Do you need to migrate?" framing, the
wasi:io-to-Canonical-ABI concept mapping table, three before/after WIT
patterns (stream-plus-future, write-direction flip, two-step calls
collapsed), short per-interface notes for wasi:io/http/sockets/
filesystem/cli/clocks/random, a tooling requirements table, and a
version-pinning callout for the current RC-to-0.3.0 transition. Hook
the page into the Understanding section after WIT Reference.

Signed-off-by: Eric Gregory <eric@cosmonic.com>
@ericgregory ericgregory marked this pull request as draft June 12, 2026 18:36
Refine language for clarity and consistency in the migration guide.
@ericgregory ericgregory changed the title Add Migrating from WASI P2 to WASI P3 guide Add Async, Streams, and Futures concepts page and Migrating from WASI P2 to WASI P3 guide Jun 12, 2026
@ericgregory ericgregory marked this pull request as ready for review June 12, 2026 18:49
Apply content-ownership guidance by reframing design/async.md to
describe the Component Model primitives in P3 terms throughout, rather
than as a P2-to-P3 contrast that overlaps with wasi.dev's WASI P3 page.

- Drop the A→B→Host diagram and surrounding A/B/Host references.
- Drop P2 comparisons from the primitive descriptions and from the
  write-pattern code example.
- Rename 'Common patterns' → 'How the primitives work in WASI P3'.
- Replace 'Tooling support' (which duplicated wasmtime.md) with a
  brief 'Where to go next' pointer block.

In migrating-to-p3.md:

- Replace 'Interface notes' (40 lines of per-package detail) with
  'Interface highlights' (3 load-bearing changes + link to wasi.dev).
- Rewrite the WIT pattern openings with phrasing distinct from both
  the reframed async.md and wasi.dev/wasi-p3.
- Fix a broken intra-document anchor and a wasi:http resource count
  inconsistency (eight vs nine).

Signed-off-by: Eric Gregory <eric@cosmonic.com>
Per WASI maintainer guidance, refer to the WASI specifications as
"WASI 0.2" and "WASI 0.3" in prose, including page titles, section
headings, the migration guide's mapping table, and the new
component-model-concepts and SUMMARY entries. Filename and URL slugs
(migrating-to-p3.md, wasi-p3 in wasi.dev URLs) are unchanged.

Signed-off-by: Eric Gregory <eric@cosmonic.com>
The earlier WASI P2/P3 -> WASI 0.2/0.3 rename left several sentences
starting with or hinging on a bare "0.2" or "0.3", which reads
awkwardly. Prefix those with "WASI" so the version reads as a noun
phrase. The tooling-requirements table cells stay terse.

Signed-off-by: Eric Gregory <eric@cosmonic.com>

@vados-cosmonic vados-cosmonic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks for working on this @ericgregory

Left a bunch of nits -- I'm a bit wary of calling async func and stream<t>/future<t> "component model ABI primitives" because they are actually WIT level constructs (that get turned into actual CM primitives, depending on how you think about it)... But this is probably splitting hairs. Feel free to ignore those comments.

@@ -0,0 +1,65 @@
# Async, Streams, and Futures

WASI 0.3 is built on three new Canonical ABI primitives in the Component Model: `async func`, `stream<T>`, and `future<T>`. Together, they let interfaces express asynchronous operations that compose across component boundaries.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WASI 0.3 is built on three new Canonical ABI primitives in the Component Model: `async func`, `stream<T>`, and `future<T>`. Together, they let interfaces express asynchronous operations that compose across component boundaries.
WASI 0.3 adds new Canonical ABI primitives to the Component Model that enable async functionality. Components that target WASI 0.3 can use the new features in their WIT files:
* `async func`
* `stream<T>`
* `future<T>`
These new types let interfaces express asynchronous operations that compose across component boundaries.


WASI 0.3 is built on three new Canonical ABI primitives in the Component Model: `async func`, `stream<T>`, and `future<T>`. Together, they let interfaces express asynchronous operations that compose across component boundaries.

For migration mechanics (e.g., how a WASI 0.2 component maps onto these primitives) see [Migrating from WASI 0.2 to WASI 0.3](./migrating-to-p3.md). For the WASI release view, including the full per-interface diff, see [WASI 0.3](https://wasi.dev/releases/wasi-p3) on WASI.dev. This page focuses on the Component Model concepts themselves.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For migration mechanics (e.g., how a WASI 0.2 component maps onto these primitives) see [Migrating from WASI 0.2 to WASI 0.3](./migrating-to-p3.md). For the WASI release view, including the full per-interface diff, see [WASI 0.3](https://wasi.dev/releases/wasi-p3) on WASI.dev. This page focuses on the Component Model concepts themselves.
For migration mechanics (e.g., how a WASI 0.2 component maps onto these primitives) see [Migrating from WASI 0.2 to WASI 0.3](./migrating-to-p3.md).
For the a closer look at WASI 0.3 release, including a full per-interface diff, see [WASI 0.3](https://wasi.dev/releases/wasi-p3) on WASI.dev.
This page focuses on the Component Model concepts themselves.

Wonder if these should be info blocks or sometihng, but IMO we could use some space in between


That arrangement holds up for two-party interactions, but it falters once components are composed in a chain. If a component awaits work that another component delegates further, the readiness signal has to travel back up the chain. When readiness is expressed as a resource scoped to a single component, the intermediate component is stuck running an event loop purely to forward the wake-up to its caller; the runtime cannot help, because the resource doesn't live in a place the runtime can reach across. This is sometimes called the **sandwich problem**: an async vocabulary that describes a single hop just fine but cannot propagate readiness past one.

Native primitives close the gap. With `async func`, `stream<T>`, and `future<T>` in the Canonical ABI, scheduling and wake-up propagation become the runtime's job rather than any individual component's. Components can pass futures and streams along the chain without keeping their own event loops running to relay readiness.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Native primitives close the gap. With `async func`, `stream<T>`, and `future<T>` in the Canonical ABI, scheduling and wake-up propagation become the runtime's job rather than any individual component's. Components can pass futures and streams along the chain without keeping their own event loops running to relay readiness.
Native async primitives help close this expressivity gap. With updated Component ABI mechanics that enable `async func`, `stream<T>`, and `future<T>` available at the WIT level, scheduling and wake-up propagation become the runtime's job rather than any individual component's.
Components can pass futures and streams along without keeping their own event loops running to relay readiness, as was necessary with WASI 0.2.

@@ -0,0 +1,65 @@
# Async, Streams, and Futures

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Async, Streams, and Futures
# Native Async with WASI 0.3


Native primitives close the gap. With `async func`, `stream<T>`, and `future<T>` in the Canonical ABI, scheduling and wake-up propagation become the runtime's job rather than any individual component's. Components can pass futures and streams along the chain without keeping their own event loops running to relay readiness.

## The three primitives

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## The three primitives
## Async functions, Streams, and Futures


### Stream parameter, future return

Writes use the symmetric shape: the guest supplies the data as a `stream<u8>` parameter, and the host returns a `future` that resolves once it has consumed the stream. Stdout, stderr, filesystem writes, and TCP sends all follow this shape:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A link here to write-via-stream in-situ would be great


### Async, Streams, and Futures

The Component Model includes [`async func`, `stream<T>`, and `future<T>`](./async.md) as native Canonical ABI primitives, introduced alongside WASI 0.3. Together, they let interfaces express asynchronous operations that compose across component boundaries.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Component Model includes [`async func`, `stream<T>`, and `future<T>`](./async.md) as native Canonical ABI primitives, introduced alongside WASI 0.3. Together, they let interfaces express asynchronous operations that compose across component boundaries.
New Component Model primitives that enable use of [`async func`, `stream<T>`, and `future<T>`](./async.md), were introduced alongside WASI 0.3. Together, they let interfaces express asynchronous operations that compose across component boundaries.


## Do you need to migrate?

Not immediately. WASI 0.3 runtimes can polyfill 0.2 by mapping 0.2 imports onto native 0.3 primitives at the host boundary, and Wasmtime's `wasmtime serve` already runs both 0.3 and 0.2 components from the same binary, dispatching per component. Migration is the right call when you want:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Not immediately. WASI 0.3 runtimes can polyfill 0.2 by mapping 0.2 imports onto native 0.3 primitives at the host boundary, and Wasmtime's `wasmtime serve` already runs both 0.3 and 0.2 components from the same binary, dispatching per component. Migration is the right call when you want:
Not immediately -- WASI 0.2 can be used in hosts just as before, WASI 0.3 is a purely additive change.
Separately, WASI 0.3 runtimes can polyfill 0.2 by mapping 0.2 imports onto native 0.3 primitives at the host boundary, and Wasmtime's `wasmtime serve` already runs both 0.3 and 0.2 components from the same binary, dispatching per component. Migration is the right call when you want:


Not immediately. WASI 0.3 runtimes can polyfill 0.2 by mapping 0.2 imports onto native 0.3 primitives at the host boundary, and Wasmtime's `wasmtime serve` already runs both 0.3 and 0.2 components from the same binary, dispatching per component. Migration is the right call when you want:

- Composable async across component boundaries (the [sandwich problem](./async.md#native-async) goes away).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this link may die if the other changes go in


| Tool | Minimum | Notes |
| ------------- | --------------------------------------------------------------- | ------------------------------------------------------------------- |
| Wasmtime | 43+ for `wasmtime run`; 44+ for `wasmtime serve` | Enable with `-Sp3 -W component-model-async=y`. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might as well go 46+ for all of the things together?

https://github.com/bytecodealliance/wasmtime/releases#release-v46.0.0

Wasmtime now supports WASI 0.3.0 by default and the component-model-async
wasm feature is now enabled by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants