Skip to content

[FEATURE] Add native support for Wasm via WASI #67

Closed

Description

@jofoerster

Thank you for creating building mqtt-lib!!

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).

Activity

  1. fabracht commented on Mar 30, 2026

    @fabracht
    Contributor

    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.

  2. self-assigned this
    on Mar 30, 2026
  3. fabracht commented on Mar 30, 2026

    @fabracht
    Contributor

    Have you looked at WASIX instead? That may be worth a shot.

  4. jofoerster commented on Mar 31, 2026

    @jofoerster
    Author

    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)

  5. locked and limited conversation to collaborators on Apr 9, 2026
  6. converted this issue into a discussion #71 on Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions