Tech News
← Back to articles

Notes on writing Rust-based Wasm

read original related products more articles

I’ve been writing an increasing amount of Rust‑based Wasm over the past few years. The internet has many opinions about Wasm, and wasm-bindgen is — let’s say — not universally beloved, but as I get more experience with it and learn how to work around its shortcomings, I’ve found some patterns that have dramatically improved my relationship with it.

I want to be clear up front about two things:

I deeply appreciate the work of the wasm-bindgen maintainers. It’s entirely possible that there are better ways to work with bindgen than presented here; this is just what’s worked for me in practice!

I’ve seen excellent programmers really fight with bindgen. I don’t claim to have all the answers, but this post documents a set of patterns that have made Rust+Wasm dramatically less painful for me.

Unless you have a good reason not to:

Pass everything over the Wasm boundary by &reference Prefer Rc> or Arc> 1 over &mut Do not derive Copy on exported types Use wasm_refgen for any type that needs to cross the boundary in a collection ( Vec , etc) Prefix all Rust-exported types with Wasm* and set the js_name / js_class to the unprefixed name Prefix all JS-imported types with Js* Implement From for JsValue using js_sys::Error for all of Rust-exported error types

Some of these may seem strange without further explanation. Below give more of the rationale in detail.

A Quick Refresher

wasm-bindgen generates glue code that lets Rust structs, methods, and functions be called from JS/TS. Some Rust types have direct JS representations (those implementing IntoWasmAbi ); others live entirely on the Wasm side and are accessed through opaque handles.

Wasm bindings often look something like this:

... continue reading