Supporting Emscripten on Tokio

18 views
Skip to first unread message

Guy Bedford

unread,
Jun 9, 2026, 1:04:38 PMJun 9
to emscripten-discuss
Hi all,

We recently landed support for the Emscripten target in the wasm-bindgen project and are exploring its adoption more widely for its benefits over the wasm32-unknown-unknown platform agnostic target, in allowing better libc compatibility.

In the Rust ecosystem, Tokio is an async runtime that supports various targets including only the WASI targets for Wasm, but it does not yet have full support for the Emscripten Wasm target.

This means that when building Rust projects for the Emscripten target, applications using Tokio async features will likely not build correctly.

There are perhaps two main runtime variations that can work for Emscripten on Tokio here - a "hosted event loop" single-threaded runtime, with or without a JSPI switch, and a comprehensive multi-threaded runtime.

I have been fleshing out the first and simplest single-threaded hosted event loop model in https://gist.github.com/guybedford/9f534c70dd4b450294bf27eed139153f, and also have a draft Emscripten prototype that is able to get the test suite including many of the net tests passing.

Towards a formal PR I have opened an initial discussion issue on the Tokio repo in https://github.com/tokio-rs/tokio/issues/8194.

The Tokio maintainers seem open to this Emscripten target support, under the condition that there are clear maintainers for this target in Tokio. Currently myself, Hood Chatham and Ingvar Stepanyan would be able to take on this role.

I'm sharing this topic for any further feedback from the Emscripten maintainers and community on the design here and also to seek further collaborators that may be interested in reviewing and assisting with the maintenance of this target work, either formally or informally.

Sam Clegg

unread,
Jun 9, 2026, 2:05:31 PMJun 9
to emscripte...@googlegroups.com
This sounds really promising, especially with JSPI becoming more widespread (in emscripten we also have ASYNCIFY which be substituted for JSPI too, in most cases).

I don't know much about Rust or Tokio myself, so I cannot offer much guidance, but wonder if it would be good idea (once its ready) to add some basic tests to emscripten test suite (like we have for Rust itself), to make sure don't break this support as we evolve emscripten?

cheers,
sam




--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/emscripten-discuss/eee88b87-565b-463e-a473-02b2a6a0420an%40googlegroups.com.

Thomas Lively

unread,
Jun 9, 2026, 2:39:20 PMJun 9
to emscripte...@googlegroups.com
Sounds like a great idea. I have some questions to make sure I understand the plan.

Given that Rust coroutines are stackless, how would JSPI enter the picture?

More generally, what is the envisioned story for the interaction between (sync/async) Rust and (sync/async) JS? Will async Rust be able to freely call async JS? What will the relationship be between the JS event loop / microtask queue and the Tokio runtime?

Is the idea to start with the single-threaded runtime and extend it with multithreaded support later, or are these runtime architectures mutually incompatible?

Guy Bedford

unread,
Jun 10, 2026, 6:17:03 PM (13 days ago) Jun 10
to emscripte...@googlegroups.com
> Is the idea to start with the single-threaded runtime and extend it with multithreaded support later, or are these runtime architectures mutually incompatible?

Tokio directly branches the runtime on the single-thread / multi-thread usage scenarios ("flavors"), so that these separate features can largely be considered orthogonal. I am only really able to dedicate work to the single-threaded runtime here currently, so perhaps someone else can pick up the multi-threaded work after (it may well not be that difficult).


> Given that Rust coroutines are stackless, how would JSPI enter the picture?

It exactly doesn't have to, unless there truly is blocking IO.


> More generally, what is the envisioned story for the interaction between (sync/async) Rust and (sync/async) JS? Will async Rust be able to freely call async JS? What will the relationship be between the JS event loop / microtask queue and the Tokio runtime?

The hosted event loop concept is to have a budged drive() call that is able to cooperate with the JS event loop. async Rust -> async JS works fine without JSPI, only sync Rust -> async JS (e.g. when using block_on) is the issue which is an error without JSPI and with JSPI can still be supported. The epoll loop in this hosted runtime remains non-blocking.

I currently just have the single-threaded prototype supporting async libc calls, I'm looking to see if I can support this both with and without JSPI as a configuration, which is useful to e.g. `#[tokio::test]` which needs to run everything synchronously from a Rust perspective. Will see if this works out fully yet.

Please feel free to hop in on the related Tokio thread as well as that gets worked through, and I can also share the PR here when it's eventually ready.


Reply all
Reply to author
Forward
0 new messages