Why I'm excited about WebAssembly

2022-08-07

A little more than a decade ago, the engineers at Mozilla started thinking about how they could enable resource and compute heavy applications like games to be run inside the browser. This gave rise to asm.js which is a low level subset of javascript and since it's just javascript, it also enabled portability across browsers. Languages like C/C++ could compile to asm.js and high performance libraries written in these languages could be brought to the web. This came with its own issues though - the parsing of the modules was a bottleneck and the asm.js code was ultimately just javascript which comes with some rough edges. The idea that such low level asm.js modules should actually be supported as a binary format is what gave rise to WebAssembly in 2015. WebAssembly modules can be much smaller as compared to their asm.js versions and decoding these modules can be a lot faster than parsing javascript.

The original design docs for WebAssembly focus on making it work well on the web but also keep in mind the need for it to work in non-web environments such as embedded devices, data centers and edge computing. So essentially WebAssembly can be thought of as a compile target that aims to achieve maximum portability across different platforms and not just run within web browsers. That portability is made possible by keeping the core feature set as small as possible and adding required features on top depending on the execution context. While on the web WebAssembly will use the Web API's provided by browsers, standardization efforts like WASI aim to provide the functionality for it to work in non-web environments.

Another thing that adds to the portability of WebAssembly is that it enables code written in different languages to work together. All code, irrespective of the language it was written in will be compiled to WebAssembly which will then be executed by a common runtime. The fact that Wasm modules do not need to be independently compiled for different OSes, platforms and architectures also enables a much more flexible deployment scenario than containers.

Besides portability, the other significant feature of WebAssembly is security. WebAssembly modules will run in a sandboxed environment independent of each other and are constrained by default to the security model of the environment they're running in. As per the design docs,

"Modules must declare all accessible functions and their associated types at load time, even when dynamic linking is used."

This model protects users by not providing client code default access to host resources like the file system or API's such as network calls. Any such requests to system resources or APIs have to be explicitly allowed.

The other aspect that enables a more secure experience with WebAssembly is memory isolation. No module shares the memory of any other module. Any data that needs to be shared across modules needs to be shared as function calls. The WebAssembly Component Model allows for this data exchange to take place and the great thing is that there is no serialization/deserialization required to transfer data between different modules. The runtime can make direct copies of the data between the memory space of the communicating modules. This shared-nothing, explicit communication model allows for more secure application code. Check out Lin Clarke's blog post introducing the Bytecode Alliance where she gives more details about this security model.

Taken together, all the features that WebAssembly offers add up to offer a very different way of application deployment that is bound to appeal to developers. Already, IDE's with bundled development environments, Compute intensive applications like Adobe Photoshop, streaming platforms like Amazon Prime, BBC iPlayer and Disney+, machine learning applications like Translation Engines and industry Game engines are either being ported to run completely in your browser or their existing parts are being implemented in WebAssembly to realise security and performance gains. Scenarios like scale-to-zero compute have now become feasible.

Expanding on one of the examples mentioned above, WebAssembly enabled Stackblitz to build environments called WebContainers that can run node.js completely inside the browser. Package installs and builds were also said to be much faster than in local dev environments. This opens up some exciting possibilities. A user would now be able to navigate to any repository and with the click of a button have a development environment with all dependencies and tools available - inside their browser! Check out the demo. It's pretty cool.

A real world use case that I'm excited about is the online collaboration beyond the simpler scenarios we have currently. Imagine a Digital Audio Workstation (DAW) like Ableton running not on a single server but on the laptops of different people mixing tracks in real time on the same project even as an artist records instruments or vocals in a completely different place. All compute intensive tasks could happen on the local machines giving an extremely smooth experience. Audio plugins could be written in WebAssembly using a language of choice and could then be easily used in the project. Indeed, Ableton already seems to be experimenting on these lines.

In summary - together with the WebAssembly specification, the WebAssembly Systems Interface (WASI) and the WebAssembly Component Model enable the development of sandboxed applications with a shared nothing architecture that makes any communication of state explicit and protects the user from malicious or vulnerable code.

For more examples of the use cases that WebAssembly is aiming to solve, check out the WebAssembly and the component model docs.