· via Cloudflare blog
Cloudflare brings native Rust and Tokio apps to Workers via wasm-bindgen Emscripten target
Cloudflare's experimental Emscripten target for wasm-bindgen lets native Rust apps, including Tokio-based servers such as a Minecraft server in a Durable Object, run on Workers.

What Cloudflare announced
Cloudflare has published the first experimental preview of first-class support for the wasm32-unknown-emscripten Rust compiler target in wasm-bindgen, the open source toolchain that powers Rust WebAssembly applications on the company's V8-based Workers Runtime. According to the Cloudflare blog, the change makes it possible to run native Rust code — including applications built on the Tokio async runtime — directly on Workers, as well as on the web and in Node.js.
The feature is still pre-release. Cloudflare has released experimental patchsets alongside example applications covering building Emscripten Rust Workers, running the Tokio runtime inside a Worker, and using TCP sockets with Emscripten and Tokio.
How the two toolchains learned to cooperate
Emscripten, a WebAssembly compiler toolchain originally created by Mozilla and maintained today by Google engineers, bridges native code and the web platform by virtualizing features such as timers, file system operations, and sockets. Cloudflare says the effort to add an Emscripten target to wasm-bindgen began with Google more than a year ago, with the Cloudflare engineers who maintain wasm-bindgen later reviewing and extending the work.
The obstacle was architectural: both Emscripten and wasm-bindgen assumed they were in charge of loading JavaScript and generating the final JS and Wasm output, so teams had to pick one toolchain and forgo the other. Mitch Foley of Google's Portable Toolchains team hit this limit when another Google team wanted to use wasm-bindgen to interface with their JavaScript from C++ code compiled by Emscripten. Foley and his colleague Yifan Yang proposed a division of labor: Emscripten keeps driving the build, loading the Wasm module, and producing the accompanying JavaScript, while wasm-bindgen emits a smaller portable form of its bindings that plugs directly into Emscripten's library system. With feedback from Google's Portable Toolchains and Wasm Tools teams plus Cloudflare engineers, the required changes landed in both projects and are exposed through a new -sWASM_BINDGEN configuration. It works in both directions: Emscripten-built C++ can link static wasm-bindgen Rust code, and Rust projects can compile for the Emscripten target while keeping both binding layers available.
Library compatibility on Workers
Because Workers supports Web Platform APIs and Node.js compatibility, Cloudflare implements Emscripten using its Node.js compilation flags, virtualizing native platform features on top of existing Node.js APIs. The company reports much better library compatibility for Rust Workers as a result. Many crates worked unmodified — including low-level systems libraries — since Emscripten already satisfies Rust's target_family = unix. Libraries unaware of Emscripten, such as libc, socket2, and Mio, required patches, but Cloudflare describes these as mostly small additions of explicit target_os = "emscripten" gates, and says Rust maintainers were receptive to reviewing them.
Making Tokio fit a JS event loop
Tokio needed deeper surgery. Workers are single-threaded and hosted inside a JS event loop, while Tokio's design assumes blocking operations can park a thread — a blocking socket read or an epoll wait would stall the shared event loop. Cloudflare backed two fixes: WebAssembly JavaScript Promise Integration (JSPI) and modifications to Tokio so it can integrate with an event-loop host. Cloudflare has contributed full Tokio support patchsets that are under upstream review, and the first target support patch for wasm32-unknown-emscripten has already landed in Tokio.
JSPI suits Tokio's model because it lets a blocking Wasm call suspend the WebAssembly stack and hand control back to the JS event loop, which behaves like a park. New Wasm stacks may also start while earlier ones sit suspended. The complication is that Rust does not know its stack is being switched underneath it: Tokio tracks its runtime context in a thread local, and a JSPI stack switch is not a thread switch, so a newly entered call sees context that still believes it is parked and panics as a result. Fully reentrant JSPI therefore requires the thread-local context to be exchanged on every JSPI entry, splitting state across suspended stacks.
A Minecraft server as proof
To demonstrate the capability, Cloudflare ran Pumpkin, a Rust-native Minecraft server, inside a Durable Object with TCP ingress, using real TCP sockets via Tokio.
Why it matters
Serverless runtimes have typically pushed Rust developers toward the wasm32-unknown-unknown target and a narrow slice of the crate ecosystem. By making Emscripten a first-class wasm-bindgen target, Cloudflare substantially widens the set of native Rust libraries — and full Tokio-based networking applications — that can run on Workers. The Google-Cloudflare collaboration also matters beyond Workers: a single build can now mix wasm-bindgen and Emscripten bindings across the web, Node.js, and edge platforms, and if the Tokio patches merge upstream, any event-loop host gains a path to running Rust async code.
- #rust
- #webassembly
- #cloudflare-workers
- #serverless
- #tokio