Current date May 18, 2026
Programming

Rust for JavaScript developers: the leap worth taking

URL copied
Share URL copied

Rust appeared on web developers’ radars years ago, but adoption was slow. In 2026 the landscape changed: Rust powers critical tools in the JS ecosystem (Biome, Oxc, Rolldown, the SWC compiler) and WebAssembly makes it indispensable on the frontend. It’s time to learn it.

Types: from `any` to the safest system in the world

| JavaScript/TypeScript | Rust equivalent |

| ———————- | ——————————– |

| `number` | `i32`, `u32`, `f64`, … |

| `string` | `String` (heap) / `&str` (slice) |

| `T \| null` | `Option` |

| `T \| Error` | `Result` |

| `any[]` | `Vec` |

| `{ [key: string]: T }` | `HashMap` |

fn divide(a: f64, b: f64) -> Option {
    if b == 0.0 {
        None   // equivalent to null without the billion-dollar mistake
    } else {
        Some(a / b)
    }
}

fn main() {
    match divide(10.0, 0.0) {
        Some(result) => println!("Result: {result}"),
        None => println!("Division by zero"),
    }
}

Error handling: `Result` is the `Promise` of Rust

In JS you handle errors with `try/catch` or `Promise` chains. In Rust, `Result` is the idiomatic way:

use std::fs;
use std::io;

// Before: without the ? operator
fn read_config_verbose() -> Result {
    let content = match fs::read_to_string("config.toml") { // [!code --]
        Ok(c) => c,                                            // [!code --]
        Err(e) => return Err(e),                               // [!code --]
    };                                                         // [!code --]
    Ok(content.to_uppercase())
}

// With the ? operator (equivalent to JS await, but for errors)
fn read_config() -> Result {               // [!code ++]
    let content = fs::read_to_string("config.toml")?;       // [!code ++]
    Ok(content.to_uppercase())                               // [!code ++]
}

Closures and higher-order functions

The syntax is different but the concept is identical:

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // map + filter + collect (like Array.map + filter in JS)
    let double_evens: Vec = numbers
        .iter()
        .filter(|&&x| x % 2 == 0)  // [!code highlight]
        .map(|&x| x * 2)            // [!code highlight]
        .collect();

    println!("{:?}", double_evens); // [4, 8]
}

Rust → WebAssembly: the bridge to the frontend

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}
# Compile to WASM
wasm-pack build --target web
import init, { fibonacci } from "./pkg/my_project.js";

await init();
console.log(fibonacci(40)); // ~10x faster than pure JS version

Where to start

1. [The Rust Book](https://doc.rust-lang.org/book/) — the best documentation of any language.

2. Rustlings — interactive exercises in the terminal.

3. [Rust by Example](https://doc.rust-lang.org/rust-by-example/) — learn with real examples.

4. Build something with `wasm-pack` and use it from your current web project.

> The learning curve is real, but the Rust compiler is the best teacher you’ll find: its error messages are detailed, accurate, and almost always include the solution.

Share URL copied

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Active0
AI3
AI & Automation10

Exclusives

Lifestyle

Related Articles

TypeScript 5.x: features that change how you write code

Practical review of the most impactful new features in TypeScript 5.x —...