bytecodealliance / bytecodealliance/wasi-rs

Improve Rust ergonomics for wasip3 async main functions

Open
#110 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
370
Forks
65
Avg merge
7m
Merged PRs (30d)
3

Description

It would be nice to write this kind of program:

```rust
extern crate wasi;

async fn main() {
let one_millisecond = 1_000_000u64;
wasi::clocks::monotonic_clock::wait_for(one_millisecond).await
}
```

However, there are a number of things that get in the way. Right now you need something like:

```rust
extern crate wit_bindgen;

wit_bindgen::generate!({
inline: r"
package test:test;

world test {
include wasi:clocks/imports@0.3.0-rc-2025-08-15;
include wasi:cli/command@0.3.0-rc-2025-08-15;
}
",
// Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
features:["clocks-timezone"],
async: [
"wasi:cli/run@0.3.0-rc-2025-08-15#run",
],
generate_all
});

struct Component;
export!(Component);

impl exports::wasi::cli::run::Guest for Component {
async fn run() -> Result<(), ()> {
wasi::clocks::monotonic_clock::wait_for(one_millisecond).await
Ok(())
}
}

fn main() { unreachable!("main is a stub"); }
```

Which:
1. It's weird to have the stub main function
2. It would be nice to have the same `impl std::process::Termination` setup for `run` so we don't have to `OK(())`
3. Would be nice to have the `wasi::cli::run::Guest` implementation produced automatically and just call the `async fn main()`
4. Would be nice to avoid having to explicitly declare `wasi:cli/run` as async when defining `async fn main()`

Alex mentioned that something like this might be possible, and it seems 95% of the way there:
```rust
#[wit_bindgen::async]
async fn main() {}
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing the current wit_bindgen::generate! path and the wasi:cli/run Guest wiring shown in the issue. Compare that flow with the proposed #[wit_bindgen::async] async fn main() form, including termination handling and implicit async configuration. Done means an async main can replace the stub and manual Guest implementation without the listed boilerplate.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, wasm
Domain
operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.