A guided path for JavaScript and Node developers learning Rust.
Learn systems-language discipline from a JavaScript starting point.
This track is for developers who already think in JavaScript and Node and want to understand how Rust changes the way code is modeled. It focuses on ownership, explicit state modeling, `Result` and `Option`, traits, and Rust-style testing.
before you start
- $You already write real JavaScript/Node code. This path assumes professional instincts, not beginner-level programming lessons.
- $Expect comparison-first modules: each stop starts from familiar JavaScript/Node habits, then shows where Rust agrees or pushes back.
- $Plan to practice the target ecosystem directly — syntax, testing, and design choices should feel native by the end, not translated.
by the end you can
- →Read and write idiomatic Rust without translating every line back through JavaScript/Node.
- →Spot which JavaScript/Node instincts transfer cleanly and which ones need a different Rust mental model.
- →Use the six modules as a working checklist when you build your first real Rust tool, service, or feature.
syllabus
6 modules, one capstone.
Mindset shift
Translate from JavaScript and Node's flexible runtime culture into Rust's explicit, compiler-shaped model.
Ownership and borrowing
Learn the Rust concepts that most sharply differ from JavaScript's garbage-collected object model.
Enums and pattern matching
Replace flexible tagged-object habits with Rust enums and exhaustive matching.
Result, Option, and errors
Translate JavaScript's thrown errors and nullable values into Rust's explicit outcome types.
Traits and generics
Learn how Rust shares behavior and abstraction without the inheritance instincts common in JavaScript.
Testing in Rust
Translate familiar JavaScript testing habits into Rust's built-in testing style.
track reference
Keep the shared translation aids in one place.
These are track-wide lookup tables and task patterns, not lesson-specific reading. Use them when you need a quick reset on the recurring source-to-target language translations.
Data type mappings
Recheck the building blocks when a translation starts to wobble.
JavaScript/Node
string
Rust
String or &str
Common operations
- Template literals become format! or println! calls in Rust.
- Choose owned String versus borrowed &str intentionally.
- Do not carry JavaScript coercion habits into Rust string APIs.
JavaScript/Node
array
Rust
Vec<T>
Common operations
- Use push(...) in both languages but keep element types explicit in Rust.
- Filter/map chains remain possible through iterators, but the type system participates in the transformation.
- Avoid assuming mixed dynamic shapes are free in Rust.
JavaScript/Node
object
Rust
struct / enum
Common operations
- Use named structs and enums instead of broad object literals.
- Keep legal variants explicit instead of relying on ad hoc runtime object shapes.
- Choose enums when variant state matters and structs when the shape is stable.
JavaScript/Node
undefined / missing value
Rust
Option / Result
Common operations
- Model ordinary absence with Option and failure with Result.
- Keep missing-value semantics separate from operational failure.
- Use match or combinators instead of JavaScript-style falsy checks.
Comparative cheat sheet
Keep the most common tasks visible while you practice.
| Task | JavaScript/Node | Rust |
|---|---|---|
| Define a function | function greet(name) {
return `hello ${name}`;
} | fn greet(name: &str) -> String {
format!("hello {}", name)
} |
| Format a string | const message = `user=${id}`; | let message = format!("user={}", id); |
| Add to a collection | items.push(value) | items.push(value); |
| Handle missing values | if (!user) { return null; } | if user.is_none() {
return None;
} |
| Test a function | test("slugify", () => {
expect(slugify("Hello")).toBe("hello");
}); | #[test]
fn slugify_works() {
assert_eq!(slugify("Hello"), "hello");
} |
capstone
Ship a small Rust project that proves the mental model stuck.
Build one focused artifact in Rust using the same comparison-first habits from the track: start from a familiar JavaScript/Node shape, then deliberately redesign it the way Rust expects.
- ●Translate a familiar JavaScript/Node data flow into idiomatic Rust structure instead of preserving the old shape by force.
- ●Apply the early modules to data modeling, control flow, and API boundaries before you add tooling, polish, or deployment concerns.
- ●Use the later modules to verify, test, and package the result the way Rust developers expect to see it shipped.
ready?
Start with module 01 — Mindset shift.