You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE] Add native support for Wasm via WASI #67
Describe the solution you'd like
There are currently no MQTT brokers that support being run independently as a Wasm component (e.g. in Wasmtime). By combining WASI (Preview 2 or 3 in the future) APIs and your MQTT crate, it would be possible to run your broker in standalone Wasm runtimes anywhere (IoT devices, or as a "Wasm-Microservice").
Does this fit the scope of your project?
Describe alternatives you've considered
There are no alternatives out there currently (or at least I did not find any existing broker with support for Wasm WASI)
Example implementation
I created a (working) draft implementation for this: jofoerster#1 (local PR to follow contribution guidelines). It contains a separate wasi crate, that uses a custom async executor. It can directly be run using the wasmtime cli (see README).
Thank you for the suggestion. In fact, I have worked on a prototype for the WASI crate a few months back. Here's a summary of the work done at the time.
What was built
A complete crates/mqtt5-wasi/ crate (~3200 LOC) providing:
Full MQTT v5.0 client (WasiMqttClient) and broker (WasiBroker) for WASIp3
WASIp3-native TCP transport using persistent streams
E2E test infrastructure (Docker + wasmtime with -Sp3 flag)
Extensive patterns doc (WASI-PATTERNS.md) capturing all the hurdles
The hurdles encountered. These are not necessarily deal-breakers, but they are an indication of future changes, i.e., extra work.
WASIp2 has no async support.
WASIp3 async model is fundamentally different — host-managed "waitable-sets", not tokio. futures::select!/join! deadlock. Must use wit_bindgen::spawn() + flume channels for multiplexing.
TCP writes are single-shot
Byte-at-a-time reads — stream.next().await returns one byte, not a buffer. Custom read_exact() loop needed for MQTT header parsing.
Tokio incompatibility — tokio's reactor doesn't run in WASIp3. Target-gated to only pull tokio::sync primitives.
Time crate confusion — browser WASM needs web-time, but WASIp3 supports std::time. Fixed with cfg!(all(target_arch = "wasm32", not(target_os = "wasi"))).
Major road blocks
TLS/QUIC: Feature flags defined but not implemented (WASIp3 has no native TLS; Quinn needs OS sockets)
Rapidly evolving tooling: Pinned to wasip3 0.4 / wit-bindgen 0.51 — likely stale by now
The prototype itself is complete, but WASIp3 spec still in preview (rapidly changing APIs). This adds an unnecessary burden on maintenance.
I guess the main problem is that "useful" WASI for network IO is still a prototype. And, as a prototype, it's still missing important bits here and there. Plus, some polishing would be necessary to make it more "compatible" with current patterns. The "Byte-at-a-time" reads issue is a good example of it. Not a deal breaker, but having to add a read loop to maintain compatibility with normal buffer reads just feels wrong. This may have improved in newer builds.
My conclusion at the time, and now still: WASI is not there yet.
I can't argue against your arguments about WASI being immature, the maintenance concerns and the workarounds for missing async support.
WASIX is no real option for me unfortunately, as I need to stick to the official Wasm standard and do not want to rely on "third party solutions".
I did some benchmarks/simple tests on my WASI implementation and despite the workarounds it performs really well for my use case. So thank you again for creating mqtt-lib and I might get back to this, as soon as WASI p3 is released (should be very soon)
Activity
fabracht commentedon Mar 30, 2026
Thank you for the suggestion. In fact, I have worked on a prototype for the WASI crate a few months back. Here's a summary of the work done at the time.
What was built
A complete crates/mqtt5-wasi/ crate (~3200 LOC) providing:
The hurdles encountered. These are not necessarily deal-breakers, but they are an indication of future changes, i.e., extra work.
Major road blocks
The prototype itself is complete, but WASIp3 spec still in preview (rapidly changing APIs). This adds an unnecessary burden on maintenance.
I guess the main problem is that "useful" WASI for network IO is still a prototype. And, as a prototype, it's still missing important bits here and there. Plus, some polishing would be necessary to make it more "compatible" with current patterns. The "Byte-at-a-time" reads issue is a good example of it. Not a deal breaker, but having to add a read loop to maintain compatibility with normal buffer reads just feels wrong. This may have improved in newer builds.
My conclusion at the time, and now still: WASI is not there yet.
fabracht commentedon Mar 30, 2026
Have you looked at WASIX instead? That may be worth a shot.
jofoerster commentedon Mar 31, 2026
Thank you for the quick answer!
I can't argue against your arguments about WASI being immature, the maintenance concerns and the workarounds for missing async support.
WASIX is no real option for me unfortunately, as I need to stick to the official Wasm standard and do not want to rely on "third party solutions".
I did some benchmarks/simple tests on my WASI implementation and despite the workarounds it performs really well for my use case. So thank you again for creating mqtt-lib and I might get back to this, as soon as WASI p3 is released (should be very soon)