WebAssembly (Wasm) is a technology that has the chance to reshape how we build apps for the browser. Not only will it allow us to build whole new classes of web applications, but it will also allow us to make existing apps written in JavaScript even more performant.
In this article about the state of the Rust and Wasm ecosystem, I'll try to explain why Rust is the language that can unlock the true potential of WebAssembly.
What is WebAssembly?
WebAssembly is a binary file format that all major browsers (with the exception of IE 11) have implemented for virtual machines to run. WebAssembly has the ability to start and run much quicker than JavaScript because the binary format is simple and easy for browsers to parse and run in a highly optimized way. If you're interested in the technical details of what makes WebAssembly special, I recommend Lin Clark's posts on the subject.
So, why use it?
Although I originally began looking into WebAssembly as a means to write Rust in another environment (i.e., the browser), that's not really what makes WebAssembly special. I enjoy writing JavaScript (and especially TypeScript), and the ecosystem around web development built in JavaScript is a huge asset that shouldn't be just thrown away. WebAssembly is at its best when considered as a supplement to JavaScript—filling in when JavaScript isn't quite performant enough.
WebAssembly can be used to write entire web applications or to replace small bits of existing applications that might not be performant enough with something that runs at near native speed. Also, because WebAssembly is a native-like assembly format, many languages can be compiled down to it, meaning sharing code between other platforms and the web is now much more practical.
Other languages
Many different languages can be compiled down to WebAssembly, including C# and Go, so why not use them instead of Rust? While use of a programming language is always influenced by personal preference, there are many reasons why Rust is the best tool for the job. Because these languages have large runtimes that must be included in the WebAssembly binary, they're only really practical for greenfield projects (i.e., they're practical only as JavaScript replacements). This Go wiki article on Wasm says the smallest achievable binary size uncompressed is around 2MB; this mirrors what I've seen. For Rust, which ships with an extremely minimal runtime (basically just an allocator), the "hello, world" example compiles to 1.6KB on my machine without any post-compile size optimizations (which could bring it down further).
This is not to say that the future of Go or C# in the browser is bleak—I'm quite excited about what might come from those efforts. But the reality is that these technologies will probably always be best for greenfield projects.
C and C++ ship with very small runtimes, just like Rust, and thus can be practical for embedding inside existing apps and libraries. However, Rust makes it really easy to create WebAssembly binaries that have fairly idiomatic JavaScript interfaces using the tools we'll explore in the other articles in this series, while the process in C and C++ is much more manual. The tooling in Rust is absolutely fantastic, and I think it makes the entire experience much more enjoyable. Rust is also a much more memory safe language meaning that a whole class of bugs that are common in C and C++ are impossible to have in safe Rust. If you're used to memory safe languages like JavaScript, Java, and C#, (and even if you're not), you probably want to go with Rust.
Let's keep going!
If you're interested in WebAssembly, I still encourage you to dive into whichever WebAssembly-supported language makes you happiest—whether that's C++, C#, or something else. If you're interested in learning more about Wasm development in Rust, let me know in the comments. Next, I will cover calling Rust from JavaScript. And if you'd like a more comparative look at Rust's story vs. the story for other languages like C and Go, let me know, and I will write about it more in the future.
3 Comments