Day-0 → Month-3 · the web's lingua franca
Languages / JavaScript

JavaScript

The most-deployed language on the planet. JavaScript is two things at once — a loose dynamic language and a sophisticated runtime built around an event loop. Modern JS (ES2015+) is unrecognisable from the 1995 version. The week covers the language and the runtime; TypeScript is a separate track we keep out of this path.


Why JavaScript.

JavaScript runs everywhere. Browsers (it had no choice, since 1995), Node and its successors (Deno, Bun), Cloudflare Workers and Vercel's edge runtimes, React Native mobile apps, Electron desktop, embedded scripting engines, even as a target for WebAssembly compilation. No other language is deployed in as many places.

The trade: it grew organically. Multiple this-binding rules, coercion surprises, two equality operators, two module systems. Modern JS (ES2015+) makes most of these manageable — but you still need to know the legacy traps to read existing code. The week is about modern JS; the legacy is in the "Common mistakes" section.

The 12 mental models.

Twelve ideas that, once internalised, make the rest of the language read naturally. The fixes for "JS is weird".

  1. Day-zero

    Event loop

    Single thread, one queue. Callbacks, promises, microtasks. Why "blocking the main thread" is a thing.

  2. Day-zero

    Closures

    Functions remember the variables in scope where they were defined. The lever under every callback, every middleware.

  3. Day-zero

    Prototypes

    Objects inherit from objects via the prototype chain. ES6 classes are syntactic sugar over this; the chain is still underneath.

  4. Day-zero

    this binding

    Four rules — new, explicit (call/bind), implicit (method call), default. Arrow functions opt out and inherit from enclosing scope.

  5. Day-zero

    Promise

    A value that arrives later — or doesn't. .then / .catch / .finally for composition; async/await sugar over it.

  6. Practitioner

    Hoisting

    var declarations and function declarations are "hoisted" to the top of scope. let/const are not. Avoid var; the hoisting goes away.

  7. Day-zero

    Truthy / falsy

    The 6 falsy values: false, 0, "", null, undefined, NaN. Everything else is truthy. Including empty arrays and empty objects.

  8. Day-zero

    Type coercion

    "" == false is true. 0 == "0" is true. Always === . Coercion is a feature; only opt in with explicit Number()/String()/Boolean().

  9. Practitioner

    Destructuring

    Const {a, b} = obj. Const [x, y] = arr. The pattern that makes function signatures and assignments terse.

  10. Practitioner

    Iterables

    Anything with [Symbol.iterator]. Strings, arrays, sets, maps, generators. for-of works on all of them.

  11. Practitioner

    Modules

    import/export (ESM) or require/module.exports (CommonJS). ESM is the modern way; CommonJS still rules legacy Node.

  12. Runtime

    V8 / engine

    JIT-compiled. Inline caches, hidden classes, the optimizer (TurboFan), the deoptimizer. Why predictable shapes matter for performance.

Day-zero — the first hour.

  1. Install Node. nodejs.org — pick latest LTS (v20+). Or use your OS package manager / nvm / fnm.
  2. Verify. node --version and npm --version. Expect 20.x and 10.x respectively.
  3. Editor. VS Code is the de-facto default for JS — the language server gives you auto-completion and type hints from JSDoc comments without any TS configuration.
  4. Run JS three ways. node hello.js, the Node REPL (node), and the browser console (F12).
  5. Sanity-check formatter. npx prettier --write hello.js works without installation.

Day-1 to Day-7.

DayTopicTask
1 Hello, JavaScript Install Node. node hello.js. Open the REPL. Open browser devtools console. Three ways to run JS.
2 Data shapes Arrays + .map/.filter/.reduce. Objects + destructuring + spread. Build a function that takes ({a, b, ...rest}) and uses them.
3 Flow, equality, optional chaining Internalise === vs ==. Use ?. and ?? . Iterate three ways: for, for-of, .forEach. Pick when each is right.
4 Functions, closures, this Write a function that returns a counter (closure). Test the four `this` rules. Compare arrow vs function.
5 Async — promises + await Chain three promises with .then. Rewrite with async/await. Try Promise.all and Promise.race.
6 The platforms Node: fs.readFile + http.createServer. Browser: document.querySelector + addEventListener. See the same language, different APIs.
7 Error handling + idioms Define a ValidationError subclass. Throw and catch by type. Internalise the ten patterns that distinguish "knows JS" from "writes JS".

The full concept walkthrough expands each day to 2–3 deep dives.

Week-1 to Month-3.

Seven tracks for where the next 90 days go. Pick by what your day-job touches.

  1. Track

    TypeScript (separate language)

    A separate, typed language that compiles to JS. Worth learning as its own track once you are fluent in JavaScript itself. Useful at API boundaries; not strictly required.

  2. Track

    The browser DOM

    document, window, fetch, addEventListener, custom elements, IntersectionObserver. These APIs cover more UI work than most developers realise.

  3. Track

    Node.js

    The server-side runtime. fs, http, child_process, streams, the event loop with libuv. The lingua franca of "JS on the server".

  4. Track

    Frontend frameworks

    React, Vue, Svelte, Solid. Each picks a different reactivity model. Pick one; understand its rendering model deeply before learning another.

  5. Track

    Bundlers and tooling

    Vite for dev, esbuild for speed. webpack for legacy. Browser-targeted vs Node-targeted; ESM vs CJS; the moving target.

  6. Track

    Testing

    vitest (modern), jest (the legacy default). Playwright for end-to-end. The fewer mocks, the better the tests.

  7. Track

    Alternative runtimes

    Deno (TS-first, secure by default), Bun (JS-first, fast), Cloudflare Workers (V8 isolates). Node is dominant; alternatives are catching up.

The event loop in one paragraph.

JavaScript is single-threaded. Code runs to completion on the main thread. When a function asks for I/O — fetch, setTimeout, fs.readFile — the runtime sends the request off and registers a callback. Control returns to the main thread; the next synchronous code runs. When the I/O completes, its callback is added to a queue. After every synchronous call returns, the runtime drains microtasks (promise .then), then takes one task from the macrotask queue (timers, network), runs it to completion. Repeat.

This single-threadedness is why "blocking the main thread" is a thing — and why an infinite loop in one browser tab freezes the whole tab. It's also why Node can handle 100k+ concurrent connections on one CPU core: most of the time is spent waiting on I/O, and the loop interleaves them.

Books that matter.

  • JavaScript: The Definitive Guide (7th ed) — David Flanagan. The "MDN in book form". Reference-style; not a tutorial.
  • You Don't Know JS (series) — Kyle Simpson. Free online. Goes deep on the corners — closures, prototypes, this. The "weird parts" demystified.
  • Eloquent JavaScript (4th ed) — Marijn Haverbeke. Free online. The best textbook-style introduction; ramps from zero to interpreters.
  • Functional-Light JavaScript — Kyle Simpson. The middle ground between imperative JS and full FP — practical, JS-shaped.
  • Node.js Design Patterns (3rd ed) — Mario Casciaro & Luciano Mammino. Where Node-specific idioms live.
  • High Performance Browser Networking — Ilya Grigorik. Free online. Not JS-specific, but if you write web apps, every chapter pays off.

Courses & tutorials.

  • JavaScript.infojavascript.info. The single best free curriculum. Modern JS, modern style.
  • MDN's JavaScript Guide — Mozilla's official reference. developer.mozilla.org
  • Frontend Masters' JS path — Will Sentance, Kyle Simpson, Brian Holt. The platform's "Hard parts of JS" series is the canonical intro.
  • The Odin Project — free, full-stack curriculum. Heavy hands-on; light on theory. Good if you learn by building.
  • Node.js Learnnodejs.org/learn. Server-side topics — Node-specifics, streams, performance — that the JS-language curricula skip.

Documentation canon.

Talks & videos.

  • "What the heck is the event loop anyway?" — Philip Roberts, JSConf EU 2014. Still the best 30 minutes you'll spend on async JS.
  • "In the Loop" — Jake Archibald, JSConf Asia 2018. The follow-up: microtasks, tasks, animation frames.
  • "Function as a first-class citizen" — Brian Holt, Frontend Masters. The basis for everything functional in JS.
  • "V8 internals for JavaScript developers" — Mathias Bynens. How hidden classes, inline caches, and the optimiser actually shape your code's performance.
  • Ryan Dahl on Deno — multiple talks. The Node creator's "10 things I regret about Node" plus the case for the next runtime.

JS cheat sheet.

CommandWhat it does
node script.jsRun a single file.
nodeOpen the Node REPL.
npm init -yCreate package.json with defaults.
npm install <pkg>Add dependency. --save-dev for devDeps.
npm installInstall all deps from package.json.
npm run <script>Run a script defined in package.json.
npm testRun the "test" script.
npx <binary>Run a CLI without installing globally.
npm outdatedShow packages with newer versions available.
npm auditCheck for known vulnerabilities.
node --inspect script.jsRun with the Chrome devtools debugger attached.
npx prettier --write .Format everything.

Common mistakes.

  1. Mistake

    Using var

    Function-scoped, hoisted, easy to shadow. const by default, let when reassigning. Never var.

  2. Mistake

    Using ==

    Coercion is hard to predict. Always ===. The two exceptions: foo == null catches both null and undefined (sometimes useful).

  3. Mistake

    Floating point math

    0.1 + 0.2 !== 0.3. JS uses IEEE 754 like most languages. For money: use integers (cents) or decimal.js.

  4. Mistake

    this in callbacks

    setTimeout(this.method, 100) loses `this`. Use an arrow function: setTimeout(() => this.method(), 100).

  5. Mistake

    Forgetting await

    asyncFn() returns a promise. Without await, the next line runs before the promise resolves. ESLint catches this if you ask.

  6. Mistake

    Mutating props in React

    React expects immutability. Mutating arrays/objects in state silently breaks renders. Spread, slice, or use immer.

Semicolony assets.

  • Computer networking — what fetch() runs on top of.
  • System design — JS-backed services share the same patterns.
  • Go — the comparison point for "modern backend without GC drama".
  • Rust — for when you need WASM and want types you can trust.
  • API design — REST and GraphQL, the two protocols JS most often serves.

Roadmap — when ready.

  1. Week 1. JavaScript.info chapters 1-10 + the seven-day plan above. Read modern JS fluently.
  2. Month 1. Build a CLI in Node (use commander) AND a single-page app in React/Svelte. Cover both runtimes.
  3. Month 2. Read the V8 internals — hidden classes, inline caches, the optimiser. Profile a hot path with the inspector and learn what your code costs.
  4. Month 3. Pick a specialism — a frontend framework (React/Svelte/Vue), an alternative runtime (Bun, Deno), or backend Node at scale with Fastify or NestJS.
  5. Year 1. Contribute to a major OSS JS project. Read V8 blog posts monthly. If you want types, treat TypeScript as a separate track and learn it properly.

Keep going.

JavaScript rewards persistence. The first month, the language fights you with coercion and this. By month three you're shipping modern JS, async/await flows naturally, and you can debug a missing await on a stack trace. By year one, modern JS is the most productive scripting experience available — and you can pick up TypeScript as a separate track if your project needs static types.