Stream: wasi

Topic: Is WASI based on the component model, or does it define it?


view this post on Zulip notalkonlyprox (Mar 13 2026 at 09:50):

Hey, hopefully this is the right place to ask, I apologize if not -- I am trying to get my head wrapped around the relationship between WASI and the component model, and I am not succeeding. There is a lot of conflicting information online.

Let me just cite a reputable -- and (seemingly) contradictory source -- the component-model FAQ

Q: How do WebAssembly Components and the WebAssembly System Interface (WASI) relate to each other?

The WebAssembly System Interface (WASI) is a set of APIs (specified in WIT) developed for eventual standardization by the WASI Subgroup, which is a subgroup of the WebAssembly Community Group. WASI defines interfaces, functions and types that a system or platform can expose to a WebAssembly component

Okay, so WASI is basically some standardized WIT worlds built on top of the component model, more or less?

Except:

Q: I see the terms Preview 1 and Preview 2 frequently. What do those refer to?

Preview 1 refers to the first iteration of the Component Model which was based on WITX and is now deprecated. Preview 2 refers to a newer iteration of the Component Model which uses WebAssembly Interface Types (WIT).

So, wait, hold on, the full names are WASI Preview 1 (and 2, and 3). So, literally, to quote the above, but with the names expanded, WASI Preview 2 refers to a newer iteration of the Component Model? So WASI is not built on top of the component model, but in fact is the component model?

Are there versions of the component model? Is WASI separate from the component model, but we are naming the component model versions after WASI? If WASI is just standardized API definitions, how do new features like async get included in wasip3? I am genuinely very very confused, I feel like I must be missing something obvious or important here.

That last question is really why I need to know this, I have an application in mind for the WASM component model, but it really wants some kind of async or multithreaded component execution, and I am really struggling to get my head screwed on straight figuring out how far along either of those things are in development

Bonus confusion, though this maybe starts to be a better question for other channels:

I am similarly confused by the rust target naming -- why is the target, for example, wasm32-wasip3 -- Every direct description of WASI makes me think it is a set of standardized APIs living in some WIT files somewhere, so I'd really expect that to crop up as some kind of crate with bindgen macros or something, instead of living directly inside the target.

But, then, there is all this talk of things like async in Preview 3, and that does seem like something that would need to be implemented at the target level, but it also does now sound like "standardized APIs" to me

view this post on Zulip Ralph (Mar 13 2026 at 11:46):

WASI "preview 1" is really the usage of WIT types to generate a "core set of call standards" -- like wasi:http or wasi:cli -- that core modules can use to interact across languages. The usage of WIT enables binding generators to be used for languages so that WIT itself is not something most need to see.

view this post on Zulip Ralph (Mar 13 2026 at 11:47):

This is, again, preview 1, or "v.0.1" of the component model development process -- but it is NOT components, in the sense that there is no new file type or runtime requirements beyond wasm.

view this post on Zulip Ralph (Mar 13 2026 at 11:48):

"preview 2" or v0.2.+ was the first version of the component model, in that you can create a new binary file type -- a component -- that itself wraps one or more wasm modules together across WIT interfaces, and internal to the component each module continues to be isolated against the other modules and against the host.

view this post on Zulip Ralph (Mar 13 2026 at 11:50):

Preview 3 -- or v0.3.+ -- brings the final touches to the component model, critically, async behavior as concurrency (not threading quite yet, though threading can be modeled on top of it) and streaming I/O as well as enabling chaining of component interfaces, which is critical for networking plugins and so on.

view this post on Zulip Ralph (Mar 13 2026 at 11:51):

with v0.3 we start to get the thing that enable us to compile more complex server-style stacks more or less directly to components -- webservers, dbs, python, .net or java and so on.

view this post on Zulip Ralph (Mar 13 2026 at 11:51):

now, this is a high-level sketch, and doesn't do the full justice to all the amazing work that everyone in the ecosystem has done to reach this point.

view this post on Zulip Ralph (Mar 13 2026 at 11:54):

So! WASI is merely the collection of standard interfaces defined to enable a generic but constrained "syscallish" list of things most components (or core modules) will need to use. But you do not and indeed should not use them all -- one of the critical points of the component model is that you should constrain the components to use or offer only those interfaces that it requires to achieve its purpose.

view this post on Zulip Ralph (Mar 13 2026 at 11:54):

Does that help get you started?

view this post on Zulip Ralph (Mar 13 2026 at 11:55):

Now I just spun this off the top of my head in the moment, but I'm sure others will wade in and give you better clarifications and links.

view this post on Zulip Ralph (Mar 13 2026 at 11:56):

The line WASI defines interfaces, functions and types that a system or platform can expose to a WebAssembly component should really say something like "can expose to a wasm module or component." Because while it's true that WASI was always intended to move toward components, it had to be done first with core modules.

view this post on Zulip Ralph (Mar 13 2026 at 11:57):

at some point -- people here will know when, however -- the wit language will have moved past the "preview 1" period as we approach 1.0 of the component spec and at that point, you'll likely either have to pin the tools to P1 for core modules OR there will be a shim that enables them to run.

view this post on Zulip Ralph (Mar 13 2026 at 11:58):

but where those choices are at the moment, I can't remember right now. Someone else will pick up that question.

view this post on Zulip Alex Crichton (Mar 13 2026 at 14:58):

Other parts I made add here is: yes, WASI is defined on top of the component model. From a technical perspective that's the precise layering where nothing can exist in WASI without it already existing in the component model. Effectively the component model gives a vocabulary and language by which to define WASI. While WASI has version numbers the compoent model currently doesn't really in the same way.

Another part I'd add though is that from a more social perspective (e.g. how we think about things, how things are developed, etc) the component model and WASI are quite similar. WASIp2's release was the first sort of real release of the component model. Without WASI the component model is only but so useful, and without the component model WASI can't exist, so there's a cyclic nature to the development and feature prioritization and such. WASIp3, as @Ralph mentioned, is the next iteration of both components and WASI with async support.

From a technical perspective WASIp2->WASIp3 for the component model involved adding the concept of async and then adding futures/streams to the type system. This didn't strictly speaking necessitate any changes to WASI, and you can take any WASIp2 component and run it on a runtime that supports component-model-async. However it didn't make sense to leave WASI as-is so WASI was updated to use the new types and WIT capabilities so WASIp3 exists.

view this post on Zulip Ralph (Mar 13 2026 at 14:59):

How then, @Alex Crichton, would you characterize p1 with respect to components? at that point, components really didn't exist except as the next rev, yes? Or how would you say it?

view this post on Zulip Ralph (Mar 13 2026 at 15:00):

because I may just be describing a point in time thing for p1.... but I don't wanna be under a mistaken impression....

view this post on Zulip Alex Crichton (Mar 13 2026 at 15:01):

True yeah. WASIp1 is sort of a snapshot in time where we were figuring things out. Components didn't exist yeah, we didn't know components were going to exist, but we had a lot of similar high-level goals of what we have today. We always knew that WASIp1 wasn't the end-all-be-all (just as WASIp{2,3} isn't) and so I'd characterize it as "we're working towards an end goal and needed something"

view this post on Zulip Ralph (Mar 13 2026 at 15:02):

ok, phew, it's always nice to know that I might mostly understand something. :-)

view this post on Zulip Alex Crichton (Mar 13 2026 at 15:02):

Put another way, we started with all the same high level goals we have today and released WASIp1. We learned real fast that it was a dead end and we had to revisit a lot of things at the core, namely that core modules were insufficient as a binary format container

view this post on Zulip Alex Crichton (Mar 13 2026 at 15:02):

oh sorry, no yeah you're all correct above I just wanted to add some more color

view this post on Zulip Ralph (Mar 13 2026 at 15:02):

RIGHT: that makes perfect sense

view this post on Zulip Pat Hickey (Mar 13 2026 at 15:36):

why is the target, for example, wasm32-wasip3 -- Every direct description of WASI makes me think it is a set of standardized APIs living in some WIT files somewhere, so I'd really expect that to crop up as some kind of crate with bindgen macros or something, instead of living directly inside the target.

the most basic reason for this is that because WASI gets used in throughout the std library that ships with Rust, and all changes to how std work go by way of the target triple. std ends up using the bindings that are generated by bindgen.

view this post on Zulip Pat Hickey (Mar 13 2026 at 15:38):

whether wasip1, p2, or p3, things like how std gets the program's arguments, environment variables, how it opens a file or a socket, are all defined in the wasi specs and therefore are used by std to do those things.

view this post on Zulip Pat Hickey (Mar 13 2026 at 15:42):

prior to the async stuff in wasip3, wasip1 and wasip2 defined their own mechanisms for how IO multiplexing works, similar to how unix defined https://man7.org/linux/man-pages/man2/poll.2.html , wasip3's mechanism for the same is defined in the component model itself rather than as an api defined in wasi, in order to make it flexible enough to compose programs nicely.

view this post on Zulip notalkonlyprox (Mar 13 2026 at 17:52):

Thank you all for the very detailed responses, I think I understand somewhat now -- So WASI really is the "set of standard APIs", and the term WASIp3 for example really is somewhat of a misnomer -- really it is V3 of the unnamed endeavor that led to the rise of both the component model (and the associated binary format) and WASI

And wasm32-wasip3 is so-named due to std needing WASI, that makes sense. I've been considering no-std, for this, so my perspective was a bit warped. But I think that is the wrong call, there are things (mainly advanced collection types) in std that I want to be supported, but there are also a lot of things in std that I don't want guest components to have access to, but I think I can control that in my runtime (I'm thinking wastime), right?

view this post on Zulip Pat Hickey (Mar 13 2026 at 17:53):

i mean its not really an unnamed endeavour, we just call it wasi

view this post on Zulip notalkonlyprox (Mar 13 2026 at 17:54):

That response has me back to confused, then

view this post on Zulip Pat Hickey (Mar 13 2026 at 17:54):

we just split off the component model to be specified and implemented separately from wasi, because dividing software into layers and abstractions is a natural thing to do when possible

view this post on Zulip Pat Hickey (Mar 13 2026 at 17:55):

wasip2 implies all of the aspects of the component model that were stable when wasip2 launched. wasip3 implies all of the aspects of the component model that will be stable when wasip3 launches

view this post on Zulip notalkonlyprox (Mar 13 2026 at 17:55):

Ah, okay, we are saying the same thing (I think?). In my mental model, when you did that, WASI became a modular subsystem of the overall endeavor, which then became "nameless", because at that moment, WASI stopped referring to the entire thing

view this post on Zulip Chris Fallin (Mar 13 2026 at 17:56):

maybe this helps: strictly speaking, the preview versioning applies to WASI. The component model is logically a lower layer. But colloquially, because it has been co-evolved with WASI, we often (somewhat imprecisely) refer to bits of the component model as "p3" or whatever. We've discussed before (e.g. Alex has mentioned to me) that really we should say "CM async" etc

view this post on Zulip Pat Hickey (Mar 13 2026 at 17:58):

I've been considering no-std, for this, so my perspective was a bit warped. But I think that is the wrong call, there are things (mainly advanced collection types) in std that I want to be supported, but there are also a lot of things in std that I don't want guest components to have access to, but I think I can control that in my runtime (I'm thinking wastime), right?

collection types are in alloc so you can use them without depending on any wasip3 import functions, yes.

I'm unclear on what problem you are trying to solve here. Are you a software author who wishes to run on a runtime that supports component model async, but not wasip3 imports? are you a runtime embedder who wishes to create a component model async runtime that doesn't export wasip3? do you want just, like, the filesystem to not work but network to work?

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:02):

(deleted)

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:04):

(deleted)

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:05):

Sorry, new to zulip, let me re-write those messages using quote-replies, and then delete the originals

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:05):

Chris Fallin said:

maybe this helps: strictly speaking, the preview versioning applies to WASI. The component model is logically a lower layer. But colloquially, because it has been co-evolved with WASI, we often (somewhat imprecisely) refer to bits of the component model as "p3" or whatever. We've discussed before (e.g. Alex has mentioned to me) that really we should say "CM async" etc

That does help, a lot, thank you!

Yeah, I would definitely agree with Alex. I also think that there are a lot of places where the documentation, and people, colloquially treat WASI and the CM as being the same thing (because historically they were, and then diverged - - CM is also an understandably generic-feeling name, whereas WASI is not, so I imagine that plays a role too), and that also contributes a lot to the confusion, IMO.

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:06):

Pat Hickey said:

I'm unclear on what problem you are trying to solve here. Are you a software author who wishes to run on a runtime that supports component model async, but not wasip3 imports? are you a runtime embedder who wishes to create a component model async runtime that doesn't export wasip3? do you want just, like, the filesystem to not work but network to work?

I'm toying with a plugin system for desktop software that doesn't exist yet, and I'd really like to be able to restrict those plugins to just implementing what plugins should do. I haven't decided yet what system-level capabilities make sense, but being able to restrict those (maybe even granularly) is among my concerns. Being able to execute a large number of these plugins on parallel threads is another.

I think wasip2 is capable of most of that, but the plugins might need to be able to define multiple exports that are callable from totally separate threads, and I don't know if that is even supported in any component-model/runtime version, even wasip3. I might have to find a way to let plugin authors just define separate WASM components for each function that can be called from a distinct thread

Though I am still getting this all sorted out in my head, it's a complicated project, that might not actually even be a requirement

view this post on Zulip Pat Hickey (Mar 13 2026 at 18:10):

when you are developing the desktop software plugin system you are an embedder of wasmtime. Thats also what basically every maintainer of wasmtime does for a living - maintains embeddings for our employers to use as plugin systems for our products (though typically marketing calls it something other than a plugin system, "serverless compute" or what have you). when you embed wasmtime, you'll create a wasmtime::component::Linker and then add to it whatever functionality you want the components you load to be able to call into. That can include using wasmtime_wasi::p3::add_to_linker(&mut linker) to just pull in the entire wasmtime-wasi implementation of wasi, or if you want you can pick and choose pieces of wasmtime-wasi to add to the linker, or you can use wasmtime::component::bindgen! against the wasip3 wits to make an alternative to the wasmtime-wasi crate which behaves as you like (e.g. make the filesystem go to a network filesystem). so you have a whole lot of tools to pick what level of granularity you like .

view this post on Zulip Pat Hickey (Mar 13 2026 at 18:12):

and yes you might not need wasip3 to do what you need and wasip2 might serve your needs just fine. the embeddings i maintain at the moment are wasip2 based and we will upgrade them to support wasip3 as well in the future, once wasip3 standard stabilizes and we have the engineering time available to do the integration work.

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:13):

Pat Hickey said:

when you are developing the desktop software plugin system you are ... [truncated, as I am replying to the whole thing]

Ahhh, I see, this helps quite a bit, there were a couple details of this I was murky on, thank you for spelling that out

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:17):

and yes you might not need wasip3 to do what you need and wasip2 might serve your needs just fine.

This is now properly off-topic, I can go ask in one of the appropriate channels if you think that is the better call, but I'll start here:

I am curious: Is it possible with wasip2 for someone to define a single component with, say, two separate functions A and B, that would allow me, the embedder, to execute A and B inside separate hosts on separate threads?

I think the answer is no.

But if, instead, the plugin-writer defines two separate components (and maybe this is even possible within the same overall wasm binary?), then I think possibly the answer becomes yes? Or at least it isn't nearly as clearly a definite no to me.

Similar question for wasip3, can a single module define two functions that are called in a multithreaded manner (not just cooperatively-async) by the embedder? I think the answer there is still no, right? The async features I think likely just allow for cooperative-async execution?

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:20):

We're also dipping into questions that I haven't already tried really deeply searching documentation on, so I apologize -- Just taking the opportunity to ask the questions while we are on the topic

view this post on Zulip Pat Hickey (Mar 13 2026 at 18:21):

notalkonlyprox said:

and yes you might not need wasip3 to do what you need and wasip2 might serve your needs just fine.

This is now properly off-topic, I can go ask in one of the appropriate channels if you think that is the better call, but I'll start here:

I am curious: Is it possible with wasip2 for someone to define a single component with, say, two separate functions A and B, that would allow me, the embedder, to execute A and B inside separate hosts on separate threads?

I think the answer is no.

a component can have any number of export functions, so assuming you meant that there could be a func A and B each exported, then you can take the component binary and load it on two separate hosts and execute A on one and B on the other, sure. But there won't be anything shared between the execution of those two - they will be completely separate instances of the component.

But if, instead, the plugin-writer defines two separate components (and maybe this is even possible within the same overall wasm binary?), then I think possibly the answer becomes yes? Or at least it isn't nearly as clearly a definite no to me.

You can write one component that exports A and another that exports B, or you can write one that exports both, it doesnt matter to the runtime if its only going to execute A or only going to execute B

Similar question for wasip3, can a single module define two functions that are called in a multithreaded manner (not just cooperatively-async) by the embedder? I think the answer there is still no, right? The async features I think likely just allow for cooperative-async execution?

no, theres no multithreading in wasip3 yet, this is basically gated on the https://github.com/WebAssembly/shared-everything-threads wasm proposal getting accepted/stabilized and its been slow going because its a very challenging topic. cooperative threads are a stepping stone that gets the component model closer to supporting multithreading (solving a lot of the hard infrastructural problems) before the wasm standard gives us the full power to do so

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:23):

ah, and this obviously depends on the runtime, you can just assume wastime

view this post on Zulip Pat Hickey (Mar 13 2026 at 18:26):

all of my answers are agnostic of runtime

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:28):

all of my answers are agnostic of runtime

Fair enough!

it doesnt matter to the runtime if its only going to execute A or only going to execute B

You're right, though I do think the memory consumption is a genuine concern for me-- I'd ideally not like the memory for A loaded inside a host whose only job is to execute B, for instance

So really I think a better way for me to have asked that question would have been:

Can a single wasip2 binary define two components that are individually loadable and executable on two hosts?

and, related:

If I am using wastime, will that require me to spawn two separate wastime instances, or does wastime natively support spawning multiple hosts on multiple threads?`

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:30):

no, theres no multithreading in wasip3 yet, this is basically gated on the https://github.com/WebAssembly/shared-everything-threads wasm proposal getting accepted/stabilized and its been slow going because its a very challenging topic. cooperative threads are a stepping stone that gets the component model closer to supporting multithreading (solving a lot of the hard infrastructural problems) before the wasm standard gives us the full power to do so

I see, I see, thank you also for getting me oriented on that. I saw that exact proposal, but I wasn't sure how far into implementation that has gotten, or whether that was even the latest attempt at this -- I guess the recent commit activity is a hint, though

view this post on Zulip notalkonlyprox (Mar 13 2026 at 18:31):

I don't want to take up too much of your time, I think we've gotten into questions I can answer myself with enough research time, my primary terminology confusion is cleared up, feel free to drop if you need to

view this post on Zulip Pat Hickey (Mar 13 2026 at 21:48):

Can a single wasip2 binary define two components that are individually loadable and executable on two hosts?

no, you'll need 2 binaries if this is your goal

If I am using wastime, will that require me to spawn two separate wastime instances, or does wastime natively support spawning multiple hosts on multiple threads?

no, wasmtime will not ever spawn a host process, nor will it spawn threads (one exception: the unsuccessful wasip1 threads proposal which you should ignore, forever. its very broken and should not be used by anyone ever)


Last updated: Mar 23 2026 at 16:19 UTC