Rust compiles to machine code, which runs as an executable file on your computer. You can also compile it to WebAssembly (Wasm for short) and have it run in the browser.

Until recently, if you wanted to add interactivity to a web page, or do a bunch of calculations in-browser, you'd use JavaScript. Now that Wasm is supported in all modern browsers, we can use Rust (or another compatible language) and run much closer to the metal.

Good times! Here's how to do it.

Firstly, install wasm-pack. It's a tool that helps build Rust code for the web.

Then, create a new Rust project with wasm-pack new my-wasm-project. This will generate a basic Rust library for you.

We only need to worry about src/lib.rs for now.

mod utils;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet() {
    alert("Hello, my-wasm-test!");
}

The extern "C" block pulls the alert function in from JavaScript and we "export" the greet function using pub so we can call it from JavaScript.

Those #[wasm_bindgen] annotations are what bind our Rust code to JavaScript. They tell the compiler where the Wasm module should interface with JavaScript.

The alert function ... shows an alert box on the page. Cool. Let's do something a bit more interesting!

mod utils;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}

This function calculates the nth Fibonacci number. Now we can hook it up and call this function from our page. But first, we need to compile it into WebAssembly.

Build your Wasm module with wasm-pack build --target web in the root of your project. This will create a pkg directory with a wasm.js file and a wasm_bg.wasm file.

We'll need an index.js file at the root of our project to import our Wasm module.

import init, { fibonacci } from "./pkg/my_wasm_project.js";

await init();
let result = fibonacci(32);
console.log(result); // 2178309

And an index.html to load our script.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Hello World!</title>
    <script type="module" defer async src="./index.js"></script>
  </head>
  <body>
    Hello World!
  </body>
</html>

Now serve your root directory with miniserve (or your favourite local static file server) and open index.html in your browser. You should see the result of the fibonacci function in the console.

The 32nd Fibonacci number is 2178309 btw.

And there you have it. Wasm running in-browser.

'Till next time. ✌️