mainrs said:
Compilation is done using
cargo build --manifest-path wasm/Cargo.toml --target wasm32-wasip1 --release, followed bywasm-tools component new target/wasm32-wasip1/release/library.wasm --adapt wasi_snapshot_preview1.reactor.wasm --skip-validation -o component.wasm. As far as I understood, this should lift my component into p3.
As you discovered, it won't lift your component into p3. The wasi_snapshot_preview1.reactor.wasm adapter only adapts from p1 to p2 -- it has no p3 support yet, and there are no specific plans to add such support AFAIK. Additionally, wasi-libc (on which Rust's std is based when targeting wasm32-wasip{1,2}) does not yet have any support for p3, so any features you (or your crate dependencies) use from std will bottom out in p1 or p2 imports.
Regarding a hypothetical p1->p3 or p2->p3 adapter: such a thing would certainly be useful, but it's much less urgent than the existing p1->p2 adapter was. The p1->p2 transition involved switching from core wasm modules and the WITX ABI to the component model and its canonical ABI, which meant a host had no way to provide both p1 and p2 imports to a single binary, meaning an adapter was necessary to support any mix of the two. For p2->p3, the situation is much better: p3 (and the component model async ABI it relies on) is purely additive and can be considered a superset of p2. Therefore, a host can easily run a component that imports (and exports) a mix of p2 and p3 interfaces, so an adapter is not necessary.
Practically speaking, that means you have only one option for exporting the wasi:cli@0.3.0 world currently: either generate the bindings using wit-bindgen and use them directly in a lib crate (not a bin crate, which would require a main function and pull in wasi:cli@0.2.0) instead of using std to e.g. get environment variables.
Alternatively, you could modify your host embedding to add both the p2 and p3 imports from wasmtime-wasi to the Linker, which would allow the p2 imports pulled in by std to work, as well as any p3 imports your app uses. You'd still need to manually generate the wasi:cli/run@0.3.0 export in order to export a p3-compatible async run function, though.
Eventually, we'll add native p3 support to wasi-libc and Rust via a new wasm32-wasip3 target, at which point you'll be able to run the resulting components in a "pure" p3 host with no p2 support, but we're not there yet. Also, I'm not sure what async main would look like for such a target. @Alex Crichton might have thoughts.
Everything Joel said makes sense to me, and the only bits I'd add are that we're likely to do a p1->p3 adapter at some point (basically new builds of the current adapter) but as Joel mentions we don't have that allocated for someone to work on just yet (WASIp3 is currently a moving target). For async main man I haven't thought about that at all, but I think that might be something we could support in the wasi crate (e.g. #[wasi::main] async fn main() { ... } where eventually the wasi crate will switch to WASIp3 by default
Thank you for the clarifications! That helped me out a lot in understanding what exactly these adapters are doing and why they have been created!
Regarding the async main question: wouldn't it be enough for #[wasi::main] to translate to a normal main function that spawns a blocking call to an async closure? I think I've seen such a function inside wit_bindgen::rt.
mainrs said:
Regarding the async main question: wouldn't it be enough for
#[wasi::main]to translate to a normal main function that spawns a blocking call to an async closure?
Technically, yes, that's possible, but it would prevent the host (or composed component) from making more than one concurrent call to that component instance. And maybe that's okay for a CLI-style app, but it would be more flexible to allow concurrent calls, which requires exporting an async function from the component.
mainrs has marked this topic as resolved.
I'd definitely say that the current block_on calls in the wit-bindgen tests are more of a kludge and are not "the future"
native async support is definitely the way to go (eventually)
Last updated: Dec 06 2025 at 06:05 UTC