Rust, Go, JavaScript, C/C++, and JavaScript can all run on Wasm. Here's what you need to know.
WebAssembly, or Wasm, gives developers a way to create programs that run at near-native speed in the browser or anywhere else you can deploy the WebAssembly runtime. But you generally donโt write programs in Wasm directly. Instead, you write programs in other languagesโ some better suited to being translated to Wasm than othersโand compile them with Wasm as the target.
These six languages (I count C and C++ as two) can all be deployed onto Wasm runtimes via different tooling, and with different degrees of ease and compatibility. If you want to explore using Wasm as a deployment target for your code, youโll want to know how well-suited your language of choice is to running as Wasm. Iโll also discuss the level of work involved in each deployment.
Rust
In some ways, Rust is the language most well-suited to deploy to WebAssembly. Your existing Rust code doesnโt need to be modified a great deal to compile to Wasm, and most of the changes involve setting up the right compiler target and compilation settings. The tooling also automatically generates boilerplate JavaScript to allow the compiled Wasm modules to work directly with web pages.
The size of the compiled module will vary, but Rust can generate quite lean and efficient code, so a simple โHello, worldโ generally doesnโt run more than a few kilobytes.ย Rustโs maintainers authored an entire guide to using Wasm from Rust, with details onย how to keep the size of delivered binaries smallย andย adding Wasm support to an existing, general-purpose Rust crate.
C/C++
C and C++ were among the first languages to compile to Wasm, in big part because many of the lower-level behaviors in those languages map well to Wasmโs instruction set. The early wave of Wasm demos were ports of graphics demonstrations and games written in C/C++, and those proof-of-concept projects went a long way toward selling Wasm as a technology. (Look! We can playย Doomย in the browser!)
One of the first tools developed to compile C/C++ to Wasm was theย Emscripten toolchain. Emscripten has since become a full-blown toolchain for compiling C or C++ to Wasmโfull-blown in the sense that it offers detailed instructions forย porting code. SIMD (whichย isย supported in Wasm), networking, C++ exceptions, asynchronous code, and many other advanced features can be ported to Wasm, although the amount of work varies by feature.ย Pthread support, for instance, isnโt enabled by default, and will only work in browsers when the web server has certain origin headers set correctly.
As of version 8 and up,ย the Clang C/C++ compiler can compile natively to Wasm with no additional tooling. However, Emscripten uses the same underlying technology as Clangโthe LLVM compiler frameworkโand may provide a more complete toolset specifically for compilation.
Golang
The Go languageย added support for WebAssemblyย as a compilation target in version 1.11, way back in August 2018. Originally an experimental project, Wasm is now fairly well-supported as a target, with a few caveats.
As with Rust, most of the changes to a Go program for Wasmโs sake involve changing the compilation process rather than the program itself. The Wasm toolchain is included with the Go compiler, so you donโt need to install any other tooling or packages; you just need to change theย GOOSย andย GOARCHย environment variables when compiling. You will need toย manually set up the JavaScript boilerplateย to use Wasm-compiled Go modules, but doing this isnโt hard; it mainly involves copying a few files, and you can automate the process if needed.
The more complex parts of using Go for Wasm involve interacting with the DOM. The included tooling for this viaย theย syscalls/jsย packageย works, but itโs awkward for anything other than basic interaction. For anything bigger,ย pick a suitable third-party library.
Another drawback of using Go with Wasm isย the size of the generated binary artifacts. Goโs runtime means even a โHello, worldโ module can be as much as two megabytes. You can compress Wasm binaries to save space, or use a different Go runtime, likeย TinyGoโalthough that option only works with a subset of the Go language.
JavaScript
It might seem redundant to translate JavaScript to Wasm. One of the most common destinations for Wasm is the browser, after all, and most browsers come with a JavaScript runtime built in. But itย isย possible to compile JavaScript to Wasm if you want to.
The most readily available tool for JavaScript-to-Wasm isย Javy, created and supported by theย Bytecode Allianceย (a chief supporter of Wasm initiatives). Javy doesnโt so much compile JavaScript code to Wasm as execute it in a Wasm-based JavaScript runtime. It also uses a dynamic linking strategy to keep the resulting Wasm modules reasonably small, although the size will vary depending on the features used in your program.
Python
Pythonโs situation is like Goโs, but even more pronounced. You canโt run a Python program without the Python runtime, and itโs difficult to do anything useful without the Python standard libraryโto say nothing of the ecosystem of third-party Python packages. You can run Python by way of the Wasm runtime, but itโs clunky and bulky, and the current state of the tooling for Python-on-Wasm isnโt streamlined.
A common way to run Python applications through a Wasm runtime isย Pyodide, a port of the CPython runtime to Wasm via Emscripten. One implementation of it,ย PyScript, lets you run Python programs in web pages, as per JavaScript. It also includes bidirectional support for communication between Python and the JavaScript/DOM side of things.
Still, Pyodide comes with multiple drawbacks. Packages that use C extensions (as an example, NumPy) must be ported manually to Pyodide to work. Only pure Python packages can be installed from PyPI. Also, Pyodide has to download a separate Wasm package for the Python runtime, which runs to a few megabytes, so it might be burdensome for those who arenโt expecting a big download potentially every time they use the language.


