This article is a guest post written by our interns at RIoT Secure, as part of a multi-part series exploring the evolution of WebAssembly (WASM) and the WebAssembly System Interface (WASI). Each post in this series takes a closer look at the technology’s journey, challenges, and opportunities - with a special focus on what these developments mean for IoT and secure edge computing.
Universal WASM Device I/O ABI - Introducing BRAWL’s Hardware Interfaces
In earlier posts we examined the current state of WASI, showed that WebAssembly is already practical on microcontrollers, and demonstrated zero-bloat WASM binaries in C, Rust, and TinyGo. Each of those articles pointed at the same long-term direction: WASM is more than a web technology - it is an execution target, even for resource constrained devices.
But one major piece is still missing.
-
There is no shared, portable way for a WebAssembly module to talk to real hardware I/O.
Every runtime, every vendor, every board invents its own private device ABI. If you compile a WASM binary today and want to access GPIO, I2C, SPI, UART, you end up tied to whatever ad-hoc API the host runtime exposes. Change hardware, change vendor, change runtime - rewrite the I/O layer from scratch.
Instead of waiting for standards to emerge, we decided to build a concrete proposal and publish it.
Design Goal: Universal I/O ABI for WASM MVP
We approached this not as a green-field wishlist exercise, but as a constrained engineering problem.
The question was intentionally narrow: What is the smallest possible ABI that allows a WebAssembly module to talk to real device I/O - without requiring any post-MVP WASM features, without requiring a host operating system, and without explicitly tying the module to a specific vendor SDK?
This immediately ruled out anything that depends on threads, callbacks, host objects, async runtimes, or extension proposals within WASM. The ABI must be implementable on bare metal, under a hypervisor, or inside a device process - with exactly the same function calls.
To make the ABI stable and safe across all those environments, every operation returns a 32-bit integer where non-negative values indicate success and negative values indicate defined error codes. No traps, no exceptions, no host callbacks. All data movement happens through linear memory pointers - the one thing WASM MVP guarantees everywhere.
Another explicit design constraint was symmetry: the same calls must apply whether the bus is provided by hardware or emulated in software on GPIO pins. A developer should not need two different code paths to speak to devices simply because one device has a hardware controller and another doesn’t.
Finally, the ABI had to be language-agnostic and vendor-neutral. No dependency on a specific header generator, code generator, or opinion about WIT or preview versions. A C header, a WAT import block, and a Rust FFI declaration must describe the same thing, and any host - commercial or open - must be able to implement it without inheriting someone else’s runtime stack.
The result is a set of low-level, capability-driven interfaces that obey only the rules of WASM MVP, but still provide enough structure for portable I/O on real hardware. They are deliberately minimal, because minimal is what survives standardization.
Published Interfaces (2025-10 proposal)
This initial publication focuses on the five hardware domains that form the base of almost every embedded, IoT, industrial, or edge deployment - regardless of vendor, runtime, or application domain. These are not exotic peripherals; they are the primitives from which nearly all higher-level device behavior is constructed. Whether you are reading a temperature sensor, talking to a radio module, streaming to a display, managing a boot flash, crossing into another controller, or simply debugging in the field - you end up on one or more of these five buses.
- GPIO: the ground truth of device control - every other protocol reduces to GPIO.
https://riotsecure.se/brawl?api=brawl.device.gpio - I2C: the most common digital bus for sensors and configuration devices.
https://riotsecure.se/brawl?api=brawl.device.i2c - 1-Wire: widely used in instrumentation, ID chips, temperature sensing, and bus-compatible topologies.
https://riotsecure.se/brawl?api=brawl.device.onewire - SPI: the workhorse for high-throughput peripherals.
https://riotsecure.se/brawl?api=brawl.device.spi - UART: still the universal denominator for debug, modules, GNSS, modems, and legacy bridges.
https://riotsecure.se/brawl?api=brawl.device.uart
We deliberately started at this level because if these foundations are not portable, nothing layered above them can be. A WASM module cannot be reused across boards if its GPIO assumptions change; a sensor driver is not reusable if the I2C API is vendor-specific; a secure OTA payload cannot be single-binary if SPI/UART/I2C semantics diverge between runtimes. By making these five domains consistent first, every higher-level interface built on top of them inherits portability “free of charge.”
Bonus: LED Matrix
The LED matrix interface is intentionally a higher-level, stateful, timing-aware device API built on top of core primitives at the host level. We included it to demonstrate that more complex peripherals can still be expressed cleanly under the same WASM MVP constraints, while keeping vendor-specific drivers hidden behind a stable abstraction.
In this case, the host is free to translate the portable frame format into whatever driver, shift-register topology, or animation engine it uses internally, while the WASM module remains completely unaware of those differences. The matrix API therefore serves as a proof that the same approach scales beyond “wire-level” protocols to full device classes - and, as a bonus, it makes for a very visual and fun demonstration.
Why this matters now?
WebAssembly is extending beyond browsers and into places where it mediates real hardware - edge gateways, secure coprocessors, PLCs, TPM-style enclaves, automotive domains, and microcontrollers. That migration is already underway, not hypothetical.
But the I/O layer is currently undefined. Every WASM host that needs to talk to hardware ends up inventing its own private ABI. The longer this goes unaddressed, the more fragmentation becomes embedded - not by malice, just by momentum.
Once fragmentation “hardens”, portable modules become impossible:
- a WASM sensor driver written for Runtime A will not work on Runtime B
- modules must be recompiled per vendor / per board / per runtime
- you lose OTA portability, code reuse, and third-party ecosystem potential
- the result looks exactly like the pre-POSIX UNIX landscape
This is precisely the reason WebAssembly and WASI were created to prevent this happening at the browser level. The same risk now exists at the device I/O level - and it is worse, because embedded runtimes cannot easily be retrofitted once deployed.
There is a second reason this matters now: the WebAssembly toolchain is maturing faster than the hardware interface layer. Languages, debuggers, runtimes, verifiers, component model work - all of that will outpace I/O standardization if there is no starting point. The cost of standardizing after everyone ships their own solution is dramatically higher.
Publishing a concrete proposal now forces the conversation early - while it is still tractable to converge. We are not promoting this as the one true way to go about it, but - there needs to be a starting point.
Strategic relevance
This work is not just a technical convenience - it has direct strategic consequences for anyone building runtimes, platforms, or products around secure or updatable devices. Today, almost every device is “tied to their SDK” - whoever controls the hardware I/O API controls the ecosystem: you can only ship code through their toolchain, on their boards, with their update mechanism. That model does not scale once devices must run third-party code, pass compliance, or live 10+ years in the field.
A portable I/O ABI fundamentally changes the economics of deploying code to devices. With a stable hardware interface, the same WASM artifact can run on different MCUs, in cloud simulators, inside secure enclaves, or on factory hardware without retargeting. OTA updates no longer require per-board builds - a single binary can be distributed fleet-wide regardless of vendor.
It also changes the power balance in the supply chain. Hardware becomes swappable behind a standard, unified interface, reducing vendor lock-in and increasing competition. Security review and attestation can apply to the WASM unit itself rather than a vendor-specific firmware build, improving auditability and trust in deployed logic.
For investors, standardization is a moat in a different sense: it moves the competition boundary above the hardware layer. You no longer compete on who owns the pins, but on who provides the better distribution model, security posture, lifecycle tooling, or orchestration layer. That is a market with compounding returns, not one with linear hardware margins.
RIoT Secure Perspective
For us this problem is not abstract - it intersects directly with how we deliver secure lifecycle management today. Our platform already lets customers push signed and authenticated native firmware payloads to devices in the field, rotate them, revoke them, and attest what is running. We can now extend that to WASM payloads and that model only works if the module itself is portable. Without a common I/O ABI, every deployment degenerates back into board-specific firmware and the economic advantage of secure OTA at the module level disappears.
We are not only interested in running WebAssembly safely - we are interested in replacing firmware with policy-governed, updateable WASM modules over the lifetime of a device. That only scales if hardware vendors become interchangeable behind a stable abstraction and if the delivered module does not need to be rebuilt per hardware target. Standardizing the I/O layer is what allows lifecycle management, attestation, and secure distribution to operate on a single artifact instead of N vendor forks.
We are publishing our proposals: to make portability real before the ecosystem hardens.
If you have opinions, critiques, objections, or alternative approaches - we want to hear them. Whether you are building runtimes, writing drivers, deploying secure WASM to devices, or simply care about preventing fragmentation at the I/O layer, your perspective, experience and opinions are relevant.
If you want to engage or collaborate on this effort, you can reach out to us via enquiries@riotsecure.se.
This is the fourth post in our multi-part series on WASM and WASI. In the next installment we will move from interface design to implementation strategy. How are pins reserved? How is timing enforced? How do we multiplex real hardware alongside sandboxed modules? How do hardware and software buses coexist under one abstraction?