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:
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:
Create a file src/lib.rs. Use the #wasm_bindgenattribute:
Add the below config in the Cargo.toml file:
Finally, build the WASM package using wasm-pack we installed earlier:
To use the compiled Wasm module in a browser, create an index.htmlfile:
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
Performance: Rust offers predictable performance without garbage collection (GC) pause, also called a stop-the-world (STW) pause or JIT compiler performance cliffs.
Small Code Size: Rust-generated .wasm files have small code sizes, leading to faster page loads. The .wasm files do not include extra bloat, like a garbage collector, and advanced optimizations and tree shaking remove dead code.
Seamless Interop: Rust can automatically generate binding code between Rust, WebAssembly, and JavaScript APIs.
Potential Drawbacks
Debugging: Debugging Rust WebAssembly can be difficult, but tools like console_error_panic_hook help capture Rust panics in the browser console.
DOM Access: Rust WebAssembly lacks direct access to the DOM, making it dependent on JavaScript for web app interactivity.