Use Rust to build web apps using WASM
Blog Author: Arnold Parge
High-performance web apps can be built using Rust combined with WebAssembly (Wasm). Compared to other languages like C++ or Go, Rust offers a superior toolkit and fewer binaries, making it an excellent candidate for WebAssembly due to its efficiency, memory safety, and low runtime. It has a catch too though, have explained it below.
Use Cases
• Building an entire web application in Rust. Projects like yew and leptos facilitate this.
• Using Rust for specific parts of an existing JavaScript frontend.
Currently, the Rust team is focusing on using Rust in existing JavaScript frontends
Setting up the Rust Environment
To compile Rust code into WebAssembly, follow these steps:
1. Install Rust: Follow the instructions on the official Rust website using rustup. This installs rustc (the Rust compiler), cargo (Rust’s package manager), and rust-std (Rust’s standard libraries). Ensure cargo’s bin directory is in your system PATH .
2. wasm-pack: Use wasm-pack to compile the code to WebAssembly and produce the correct packaging for use in the browser. Install it using the following command:
cargo install wasm-pack
Building Packages
wasm-pack helps compile Rust code into a WebAssembly module and creates a pkgfolder containing JavaScript and .wasmbindings.
Interacting with JavaScript
WebAssembly can work seamlessly with primitive data types, but complex types like strings and arrays require special handling. Libraries serde-wasm-bindgen simplify data serialization between Rust and JavaScript. It is possible to integrate the WebAssembly module with JavaScript and call JS functions from Rust.
We will need wasm_bindgen to call Rust functions from JavaScript. Run the below command to add wasm_bindgen to your dependencies:
Recommended by LinkedIn
cargo add wasm-bindgen
Create a file src/lib.rs. Use the #wasm_bindgenattribute:
use wasm_bindgen::prelude::*;
// Import the `window.alert` function from the Web.
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
// Export a `greet` function from Rust to JavaScript, that alerts a
// hello message.
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
Add the below config in the Cargo.toml file:
[lib]
crate-type = ["cdylib", "rlib"]
Finally, build the WASM package using wasm-pack we installed earlier:
wasm-pack build --release --target web
To use the compiled Wasm module in a browser, create an index.htmlfile:
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>hello-wasm example</title>
</head>
<body>
<script type="module">
import init, { greet } from "./pkg/hello_wasm.js";
init().then(() => {
greet("WebAssembly");
});
</script>
</body>
</html>
This HTML file imports the JavaScript code, initializes the Wasm module, and calls the greet function that we wrote in Rust.
Serve the project root with a local web server (e.g., python3 -m http.server). Ensure the web server supports the application/wasm MIME type.
Or, if you are using VSCode then, simply use the Live Server extension by Ritwick Dey to serve the index.html.
Advantages of Rust WebAssembly
Potential Drawbacks