Rust for JS Developers: What Actually Mattered
· Tutorials
What JS devs actually need in Rust \— ownership, borrowing, enums, and pattern matching. Skip chapters 1-8 of the Rust Book, focus on what transfers.
Last updated: July 14, 2026 \u00b7 6-minute read
I tried learning Rust three times before it stuck. The first two attempts I started at page one of The Rust Programming Language and gave up around chapter 8 \u2014 the ownership chapter. The third time I skipped the first eight chapters entirely and focused only on the concepts that map to things I already know from JavaScript and TypeScript. That approach worked. Here is the mapping I wish someone had given me on day one.
Ownership Is Just Closures on Steroids
In JavaScript, when you pass an object to a function, both the caller and the function hold a reference to the same object. Mutations are shared. Rust does not work that way. When you pass a value to a function, Rust moves it \u2014 the caller loses access.
JavaScript: javascript const user = { name: "Bilal" }; function greet(u) { u.name = "changed"; } greet(user); console.log(user.name); // "changed" \u2014 original was mutated
Rust: rust let user = String::from("Bilal"); fn greet(u: String) { println!("{}", u); } greet(user); // println!("{}", user); // ERROR: value borrowed after move
The mental model: think of Rust ownership as JavaScript closures that capture by value instead of by reference. Once a variable is moved into a closure (or function), the original scope can no longer access it. You can borrow it back with references (&), which is closer to how JavaScript works by default.
Borrowing Is const vs let, But Enforced
JavaScript has const and let for variable declarations, but they only prevent reassignment, not mutation. Rust\u2019s borrowing system goes further: &T gives you a read-only reference and &mut T gives you a mutable one, and the compiler enforces that you never have both at the same time.
Think of it as the compiler enforcing what JavaScript developers do manually with discipline: don\u2019t mutate data while something else is reading it.
Enums Are Union Types With Superpowers
TypeScript\u2019s discriminated unions are the closest analog to Rust enums:
TypeScript: typescript type Result<T = { ok: true; value: T } | { ok: false; error: string };
Rust: rust enum Result<T { Ok(T), Err(String), }
Rust enums carry data in each variant, just like TypeScript union types. The difference is that Rust forces you to handle every variant when you use pattern matching. TypeScript can narrow types, but it does not enforce exhaustiveness at the language level the way Rust\u2019s match does.
Pattern Matching Is Destructuring, But Required
JavaScript\u2019s destructuring is optional. Rust\u2019s pattern matching with match is required for enums and recommended for most control flow:
If you add a new variant to the enum and forget to handle it in a match, the compiler refuses to compile. This is the kind of safety net that TypeScript developers wish they had when they add a new case to a union type and forget to update the switch statement.
What I Actually Skipped
Chapters 1-8 of The Rust Book cover variables, data types, control flow, functions, and ownership basics. If you already know a programming language, you can skim these in 30 minutes. The chapters that actually matter for JS developers are 10 (generics and traits), 16 (fearless concurrency), and the sections on error handling with Result and Option.
The async runtime was the biggest surprise. Rust does not have a built-in async runtime \u2014 you need to pick one (tokio, async-std). Coming from JavaScript where the event loop is built into the runtime, this was disorienting. A Reddit thread on r/rust had a good comparison of the available runtimes.
TL;DR
- Ownership: like passing by value instead of by reference. Use clone() or references when you need shared access.
- Borrowing: the compiler enforces that you never read and write simultaneously. & for read, &mut for write.
- Enums: TypeScript discriminated unions with mandatory exhaustiveness checking.
- Pattern matching: destructuring that the compiler forces you to complete.
- Skip chapters 1-8 of The Rust Book. Start with 10, then 16, then the error handling sections.
Check out the Tauri build guide to see these concepts applied in a real project, or browse the projects for more Rust experiments. The lab has some WIP Rust tools.
---
Not affiliated with the Rust Foundation. Tested with Rust 1.82 and tokio 1.x.