WebAssembly—even after several years of standardization—is still a nascent technology.
I’ve been working with Rust and WebAssembly for nearly four years now.
This post is intended to be a distillate of that experience, formatted for developers who are interested in publishing WebAssembly code to npm.
Specifically, these are the footguns I’ve personally encountered while working on harper.js
, a WebAssembly-powered package for grammar checking at the edge.
This page should be valuable if you are even speculating on the possibility of using WebAssembly in your codebase.
The Harper package exposes one interface that captures all of its WebAssembly interactions: the Linter. This is an object that handles downloading and compiling the Harper WebAssembly module, as well as invoking functions in it. Every function returns a Promise
. There are several good reasons for that:
Whatever you do: avoid assuming that Rust libraries (like reqwest
or rand
) will be able to perform IO without some work on your end. WebAssembly alone is not capable of IO, which means any function in that category will require some amount of JavaScript to work properly.
Rather than leaving that up to the Rust toolchain to figure out, save yourself the headache and inject the necessary JavaScript functions directly into the WebAssembly module by passing them through wasm_bindgen
.
Obsidian plugins, for example, must be composed of exactly one JavaScript file, which means everything must be inlined. In the interest of keeping the bundle size small, it’s much easier for the package developer (of harper.js
) to set up inlining than the plugin developer.
On the other side of the spectrum, Chrome’s Manifest V3 disallows WebAssembly from being loaded inline.
If you plan for your package to be consumed by a variety of applications, know that it will also be consumed by a variety of bundlers. Both bundlers and applications are pretty inconsistent with their inlining and tree-shaking behavior. To avoid problems, you should provide two versions of your package:
Harper’s problem domain is not your problem domain. We have to integrate with a variety of unique applications, which means we must keep our system flexible. That may not be the case for you, which may mean these footguns do not apply. If you have any questions about any other problems the Harper project might have faced, let me know.