Hey there, you slithery Rustilian.

Have you heard the good word? Rust can now target asm.js and WebAssembly (wasm) via

emscripten. That means you can run Rust code on the web, and this capability

is available on Rust nightlies right now! Let me tell you how to Rust the web.

First, a disclaimer. This support is still a work in progress and there are

going to be a whole lot of bugs (report them, you better). It’s at the stage

where it passes the test suite, but has not been vetted on real projects at

all. And the runtime properties of the web are far different from traditional

platforms - in particular most of Rust’s I/O stack is unimplemented and will

simply fail at runtime, and badly. No work has gone into optimizing these

ports, and in particular unwinding support is known to be excruciatingly slow

in emscripten. You’re on the bleeding edge. You are a pioneer.

wasm support is almost entirely untested, but is likely to work. The wasm format

is not finalized. The way rustc emits wasm by default is by emitting a

javascript file that contains a wasm interpreter, alongside a wasm file. If

the interpreter detects that the JS engine supports wasm (which it almost

certainly won’t!) then it will use the native implementation, if not it will use

its own interpreter. So it’s gunna be slow.

The setup

We need rustup and the emscripten SDK. We’ll install the Rust nightly

toolchain and the emscripten incoming toolchain. I’ve only tested this on Linux,

but macOS should work similarly. The Windows steps will be slightly different,

but in theory it should be possible there as well.

Rust installation:

curl -L https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly source ~/.cargo/env rustup target add asmjs-unknown-emscripten rustup target add wasm32-unknown-emscripten

If you already have rustup installed, then instead of running the curl and

source commands above, just switch to the nightly toolchain with rustup default nightly .

Emscripten installation:

curl -O https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz tar -xzf emsdk-portable.tar.gz source emsdk_portable/emsdk_env.sh emsdk update emsdk install sdk-incoming-64bit emsdk activate sdk-incoming-64bit

Running some code

Hello world in asm.js:

echo 'fn main() { println!("Hello, Emscripten!"); }' > hello.rs rustc --target=asmjs-unknown-emscripten hello.rs node hello.js

Hello world in wasm:

echo 'fn main() { println!("Hello, Emscripten!"); }' > hello.rs rustc --target=wasm32-unknown-emscripten hello.rs node hello.js

Note that when I ran these commands the first time the build took a long

time. It looks like emscripten is doing a lazy compile of binaryen the first

time you run it. Just give it time.

Building a real project

That’s just the simplest thing, but cargo works too. For some examples of all this

in action see @jer’s demo page.