Ways to compile from Rust to Wasm/WASI

Posted on Feb 8, 2023

When you follow tutorials for Rust and Wasm, you’ll find different ways of how to compile your code to a .wasm file.

To untangle the confusion this post shows the ways and what the differences are.

This tutorial follows especially the wasm32-wasi target, but gives also insights to the wasm section.

1. Using the rustc compiler

If you want to compile one file (e.g. projects that are not libs), you can use the compiler directly:

rustc main.rs --target wasm32-wasi

You may need to install the target to make this work. Use the rustup command:

rustup target add wasm32-wasi

2. Using cargo build

The cargo build command is maybe the most common way of compiling a rust library. You just need to pass the target:

cargo build --target wasm32-wasi

If you don’t have the wasm32-wasi target installed, cargo will do it for you.

This will add a new target and install the standard library. More about this is described in the documentation about cross-compilation.

3. Using cargo wasi

Another way is the usage of the subcommand cargo wasi. This is a wrapper around cargo subcommands which make it easier to build Rust code for wasi.

The interface is very similar to the cargo commands, but it adds more specific things for WASI, which can be found in the documentation.

You can install the subcommand with the following command:

cargo install cargo-wasi

To compile and execute a binary you can use the run command:

cargo wasi run

This will not just compile and run your wasi module. It will do some configuration, optimization steps and check if you have a runtime installed!

Under the hood, cargo wasi is using cargo build.

4. Using wasm-pack

In the Mozilla tutorials the tool wasm-pack is often used.

The goal of wasm-pack is to serve as a toolchain for Rust to Wasm builds for the web. So not WASI. wasm-pack helps for example with the build of NPM modules and JS-interop code. So, this makes things far easier.

Once installed you can build your project for different targets like web or nodejs:

wasm-pack build --target web

Under the hood, wasm-pack is also using cargo build.

Conclusion

This post introduced four ways to compile Rust code to Wasm bytecode. But beware! Wasm doesn’t mean Wasm! Some of these tools aim modules that are especially targeted for wasm32-wasi like cargo wasi. So you always need to check the target runtime.

wasm-pack aims the web section and cargo build gives a simple interface which is used by both of them.

Which of these should you use? Well, this depends on your target and your needs. But you can conclude that the tools give different abilities and make things easier.

Further reading