Use Rust to build web apps using WASM


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 pkg
folder containing JavaScript and .wasm
bindings.
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:
cargo add wasm-bindgen
Create a file src/lib.rs
. Use the #wasm_bindgen
attribute:
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.html
file:
<!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
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.
Subscribe to my newsletter
Read articles from NonStop io Technologies directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

NonStop io Technologies
NonStop io Technologies
Product Development as an Expertise Since 2015 Founded in August 2015, we are a USA-based Bespoke Engineering Studio providing Product Development as an Expertise. With 80+ satisfied clients worldwide, we serve startups and enterprises across San Francisco, Seattle, New York, London, Pune, Bangalore, Tokyo and other prominent technology hubs.