WebAssembly and Rust: Building High-Performance Web Applications

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to WebAssembly and Rust



Modern web applications require ever-increasing performance. JavaScript, for all its merits, does not always handle computationally complex tasks — image processing, 3D rendering, cryptography, or simulations. This is where WebAssembly (WASM) comes to the rescue — a binary instruction format that runs in the browser at near-native speed.



The Rust language has become one of the best candidates for writing WASM modules: it is safe, fast, and has no garbage collector. In this article, we will explore how to compile Rust code into WebAssembly, bind it with JavaScript, and create real high-performance web applications.



Setting up the Environment for Rust + WASM



Before writing code, install the necessary tools:



  • Rust — install via rustup (official installer).
  • wasm-pack — the main tool for building WASM packages.
  • wasm-bindgen — a library for binding Rust and JavaScript.
  • Node.js and npm — for testing and building the frontend.


# Installing wasm-packcurl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

# Creating a new projectcargo new --lib wasm-examplecd wasm-example


After creating the project, open Cargo.toml and add dependencies:



[lib]crate-type = ["cdylib"]

[dependencies]wasm-bindgen = "0.2"


Writing Your First Rust Function for WebAssembly



Let's create a simple function that adds two numbers and returns the result. In src/lib.rs write:



use wasm_bindgen::prelude::*;

#[wasm_bindgen]pub fn add(a: i32, b: i32) -> i32 { a + b}


The #[wasm_bindgen] attribute automatically generates a JavaScript wrapper for this function. Now let's build the project:



wasm-pack build --target web


After building, the pkg folder will contain files: .wasm, .js (wrapper) and .d.ts (TypeScript types).



Integration with HTML and JavaScript



Let's create a simple HTML page for testing:



<!DOCTYPE html><html><head>    <script type="module">        import init, { add } from './pkg/wasm_example.js';

async function run() { await init(); console.log('2 + 3 =', add(2, 3)); // 5 } run(); </script></head><body> <h1>Rust + WebAssembly is working!</h1></body></html>


Open the file via a local server (e.g., python3 -m http.server) — you will see the result 5 in the browser console.



Working with Strings and Complex Data Types



WebAssembly only operates with numbers. For working with strings, arrays, and objects, wasm-bindgen is used, which automatically converts types.



Example: a function returning a string



use wasm_bindgen::prelude::*;

#[wasm_bindgen]pub fn greet(name: &str) -> String { format!("Hello, {}! You are using Rust + WASM.", name)}


In JavaScript:



import init, { greet } from './pkg/wasm_example.js';

await init();console.log(greet("Alex")); // "Hello, Alex! You are using Rust + WASM."


Working with Arrays (Vec)



To pass arrays, use Vec<T>. Example — a function that doubles all elements:



#[wasm_bindgen]pub fn double_numbers(arr: Vec<i32>) -> Vec<i32> {    arr.iter().map(|x| x * 2).collect()}


JavaScript code:



const result = double_numbers([1, 2, 3, 4]);console.log(r

Blogs

Book Recommendations