Skip to content

Rust for TS/JS Developers

You already think in types, async, and modules. This guide teaches Rust by mapping every concept back to the TypeScript and JavaScript you know — side-by-side, chapter by chapter.
v1.0 — 31 chapters · 330+ pages · 6 runnable projects · 100% free
31Chapters
330+Pages
6Projects
100%Free & OSS

You already know the left column. This guide teaches the right one by mapping it back to what you know — every concept, side-by-side, with the real compiler output when it matters.

typescript
type User = { id: string; name: string };
async function getUser(id: string): Promise<User> {
const res = await fetch("/api/users/" + id);
if (!res.ok) throw new Error("User not found");
return res.json();
}
rust
struct User { id: String, name: String }
async fn get_user(id: &str) -> Result<User, ApiError> {
let res = reqwest::get("/api/users/".to_owned() + id).await?;
if !res.status().is_success() {
return Err(ApiError::NotFound);
}
Ok(res.json().await?)
}

Rust’s defining idea: every value has a single owner, and the compiler tracks it at build time. No garbage collector, no use-after-free — the TS habit of sharing references everywhere becomes explicit moves and borrows.

[move] [borrow] [lifetimes] [no_gc]
ownership.rs
let s = String::from("hello");
let s2 = s; // ownership moves to s2
// println!("{s}"); // compile error: s no longer valid
println!("{s2}"); // ok — s2 owns the string

No try/catch, no throw. Errors are values: Result<T, E> and Option<T>, with the ? operator to propagate them in one character — the type system makes you handle them.

[result] [option] [question_mark] [no_exceptions]
errors.rs
fn parse_double(input: &str) -> Result<i32, ParseIntError> {
let n: i32 = input.trim().parse()?; // ? propagates the error
Ok(n * 2)
}

The syntax you know — async/await — but powered by Futures and a runtime like Tokio instead of a single event loop. True multi-threaded, fearless concurrency.

[tokio] [futures] [join] [no_event_loop]
async.rs
#[tokio::main]
async fn main() {
// both run concurrently — no event loop required
let (a, b) = tokio::join!(fetch_user(1), fetch_user(2));
println!("{a:?} {b:?}");
}

Learn by translation

Every topic opens with the TypeScript you’d write, then the Rust equivalent — you map new ideas onto ones you already own.

Honest about trade-offs

No “10× faster” hype. Real benchmarks, real rustc errors, and clear guidance on when Rust is — and isn’t — the right call.

Production-grade, end to end

Ownership and the borrow checker through async/Tokio, Serde, Axum, databases, CLI tools, security, and WebAssembly.

Code you can run

Six full capstone crates — REST API, CLI, WASM app, WebSocket chat, microservice, and a full-stack app — all compile on stable Rust.

quick/ · 20–30h

The essentials: syntax, ownership, error handling, async, and a first web API. Chapters 01–05, 08, 11, 16.

standard/ · 60–80h

Read 00–19 in order, skim the advanced topics, and build a couple of the capstone projects.

complete/ · 120–150h

All 31 chapters plus the six projects, front to back — the full systems-to-web journey.

  1. Introduction — who this is for and how to read it
  2. Why Rust for TS/JS developers — the motivation, in your terms
  3. Getting Started — install Rust and run your first program
  4. Ownership — the one idea that makes Rust click

Prefer to learn by building? Jump straight to the complete projects.

It’s free, it’s complete, and it meets you exactly where you are — with the TypeScript you already know.

start reading