DEV Community

Cover image for Rust for WebAssembly: How I Built Near-Native Performance Web Apps
RealACJoshua
RealACJoshua

Posted on

Rust for WebAssembly: How I Built Near-Native Performance Web Apps

I wanted browser performance.

Not “fast enough.”
Not “optimized JavaScript.”

I wanted real performance.

So I tried Rust + WebAssembly.

What followed was:

• Broken builds
• Missing wasm targets
• Confusing bundler errors
• A lot of “why is this not loading?”

But once it clicked?

It became one of the most powerful tools in my stack.

If you want to use Rust for WebAssembly without drowning in tooling chaos, here’s exactly what worked for me.


In this post, I’ll walk you from zero setup to running Rust in the browser — including performance use cases and production patterns.


🎯 What We’re Building

Rust + WebAssembly + JavaScript integration = 🚀
Near-native performance inside the browser = ⚡

We’ll:

• Install the Rust WASM target
• Use wasm-pack properly
• Generate JS bindings
• Integrate with a frontend
• Understand where this actually makes sense

No theory fluff. Just practical steps.


🧠 Step 1: Install the WebAssembly Target

First mistake I made?

Trying to compile without the WASM target.

Install it:

rustup target add wasm32-unknown-unknown

If this fails, check your Rust version:

rustc --version

Make sure you're on stable.


🛠️ Step 2: Install wasm-pack (Critical Tool)

This is what simplifies everything.

cargo install wasm-pack

Without wasm-pack, you'll struggle generating JS bindings.

It handles:

• Compilation
• Glue code
• Packaging
• npm compatibility


🧩 Step 3: Create a Rust WASM Project

Now initialize

cargo new rust_wasm_demo --lib
cd rust_wasm_demo
Enter fullscreen mode Exit fullscreen mode

Update your Cargo.toml:

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

[dependencies]
wasm-bindgen = "0.2"
Enter fullscreen mode Exit fullscreen mode

This enables WebAssembly bindings.


✍️ Step 4: Write Rust That Exports to JavaScript

Inside src/lib.rs:

use wasm_bindgen::prelude::*;

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

That #[wasm_bindgen] attribute?

That’s what exposes your Rust function to JavaScript.

Without it — nothing works.


🚀 Step 5: Build for the Browser

Run:

wasm-pack build --target web

This generates a pkg/ directory containing:

• .wasm binary
• JavaScript bindings
• Type definitions

If you see strange linker errors, double-check:

Rust target installed

No Windows MSVC conflicts - if you see Windows MSVC conflict check out my post on fixing rust issues on Windows here

Correct crate type (cdylib)


🌐 Step 6: Use It in the Browser

Create a simple HTML file:

<script type="module">
  import init, { add } from "./pkg/rust_wasm_demo.js";

  async function run() {
    await init();
    console.log(add(5, 3));
  }

  run();
</script>
Enter fullscreen mode Exit fullscreen mode

Open with a local server:

npx serve .

Why?

Because browsers block WASM loading via file://.

That mistake cost me 30 minutes.


⚡ Where Rust + WebAssembly Actually Shines

Don’t rewrite your whole frontend.

Use it for:

• Heavy math computations
• Cryptography
• Image processing
• Parsing large datasets
• Blockchain logic
• AI model preprocessing

For simple UI logic? JavaScript is fine.


📦 Production Pattern (What I Actually Use)

My setup:

Frontend (React / Next.js)

WASM module for heavy compute

Return results back to UI

Example pattern:

import init, { add } from "rust_wasm_demo";

await init();

const result = add(10, 20);
Enter fullscreen mode Exit fullscreen mode

Keep WASM isolated to performance-critical functions.


⚠️ Common Mistakes I Made

• Trying to use WASM for everything
• Forgetting async initialization
• Not serving via HTTP
• Fighting bundlers unnecessarily
• Ignoring bundle size

Remember:

WASM is fast — but not magic.

It improves compute speed, not DOM manipulation.


🧠 Performance Reality Check

Why is Rust fast?

Because:

• It compiles to optimized machine-level bytecode
• Memory is manually controlled
• No runtime overhead like garbage collection

When compiled to WebAssembly:

You get near-native speed inside the browser sandbox.

That’s powerful.


🏁 Final Thoughts

Rust + WebAssembly is not hype.

It’s a precision tool.

If you:

• Need serious performance
• Want memory safety
• Are building compute-heavy apps

It’s worth it.

But use it strategically.

Not emotionally.


If this helped you break into Rust WASM without losing your sanity, drop a ❤️ or share it.

Next, I might cover:

• Rust WASM inside Next.js
• Using WASM for blockchain clients
• Benchmarking Rust vs JS properly

Let me know which one you want.

Check me out at https://theacj.com.ng

Top comments (0)