Using no standard library crates with Webassembly

A Rust + Webassembly experiment using no_std crates

When working with Rust + Webassembly, you might want to use some crates in your project. Not all crates work out of the box with Webassembly yet, especially those that rely on System Libraries, File I/O, Networking, etc. With proposals such as WASI or WebAssembly Interface Types, these might work eventually but it isn’t the case yet.

The Rust Wasm book suggests:

A good rule of thumb is that if a crate supports embedded and #![no_std] usage, it probably also supports WebAssembly.

What are no_std crates?

Rust has an extensive standard library and every time you use some functionality, they need to be imported into scope. This can get very verbose and tedious! Rust automatically imports some things into every program and this is known as the prelude. The list of contents to be included in defined in the std::prelude module.

However, when working with Webassembly or Embedded systems, the environment where the code is executed might not have access to System Interface that the std library requires. #![no_std] is an attribute that indicates to Rust that the crate will link to the core crate instead which is a quasi dependency-free and platform-agnostic Rust library defining essential primitives.

The Rust-Embedded book has a great explanation about no_std environment.

You can find no_std crates on crates.io and the Awesome Embedded Rust list.

An example

A screenshot of the simulator

I’ve been experimenting with Webassembly lately and thought it would be a good educative project to make a Simulator that runs on the web for the Embedded Graphics by James Waples. The library already includes a Simulator but requires installing SDL and its development libraries even to run the demos. With Webassembly we can easily run this on a web page without installing any dependencies!

Thanks to the awesome work by James and the Rust Wasm team, it was quite trivial to implement this. I created the project using wasm-pack which is great for getting started with Rust + Webassembly work. The Embedded Graphics has great documentation on how to implement a display driver. I implemented the DrawTarget trait for drawing pixels on a <canvas> element which in turn the workflow was made great by the wasm_bindgen, js-sys and web-sys crates.

You can see a demo of the built project and find the source code on GitHub. Feel free to make code reviews or contribute or notify me if I’ve made mistakes.

References

  1. Preludes and no_std
  2. Rust Wasm book
  3. The std::prelude module
  4. wasm-bindgen