underlay
module 024–6h

JavaScript / TypeScript

Reading and writing the web's language

JavaScript runs everywhere you look: every browser tab, every Next.js site, every Node server. Its one weird idea — the event loop — confuses people more than anything else, so let's kill it first with an analogy.

The event loop: one waiter, many tables

Imagine a restaurant with ONE waiter. They take an order (start a request), the kitchen starts cooking (the slow work happens in the background), and the waiter moves on to the next table instead of standing at the kitchen door. When the dish is ready, the kitchen calls — and the waiter delivers it. That's the event loop: one thread, non-blocking, callbacks when work finishes.

Modern JS wraps those callbacks in promises, and async/await makes the code read like it's sequential even though it isn't:

jsasync/await — blocking-looking code that never blocks
// fetch is a promise: the event loop keeps serving other
// requests while the network round-trip happens
async function getModel(name) {
  const res = await fetch(`https://openrouter.ai/api/v1/models/${name}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();          // await again: parse the JSON body
}

getModel("deepseek/deepseek-v4").then(m => console.log(m.name));
jsrun this — the order proves the loop exists
executes in a sandbox
console.log("1. order taken (sync)");

setTimeout(() => console.log("3. dish ready (callback)"), 100);

Promise.resolve().then(() =>
  console.log("2. kitchen called back (microtask)")
);

console.log("4. waiter moves to the next table (sync)");

// output order: 1, 4, 2, 3
// sync runs first, microtasks beat timers — that's the event loop

Express 5: a real server in 15 lines

Node.js is JavaScript without a browser; Express is the most common way to make it answer HTTP. This is the same shape as the FastAPI server you'll build in module 5 — see both and the pattern is unforgettable:

jsserver.js — Express 5, the current default
import express from "express";
const app = express();
app.use(express.json());          // parse JSON request bodies

let items = new Map();            // in-memory store (a real DB comes in M5)
let counter = 0;

app.get("/items/:id", (req, res) => {
  const item = items.get(Number(req.params.id));
  if (!item) return res.status(404).json({ error: "Item not found" });
  res.json(item);
});

app.post("/items", (req, res) => {
  counter++;
  items.set(counter, req.body);
  res.status(201).json({ id: counter, ...req.body });
});

app.listen(3000, () => console.log("listening on :3000"));

TypeScript: the AI's best friend

TypeScript is JavaScript with types — and types are the single best tool you have for reviewing AI-written code. The AI can't silently return the wrong shape if the types scream about it, and you can't misread the contract. When the agent writes TypeScript, the compiler is your first reviewer.

tstypes make the contract visible
type RepairQuote = {
  device: string;
  price: number;      // number, not a string — mistakes become compile errors
  warrantyMonths: number;
};

function formatQuote(q: RepairQuote): string {
  return `${q.device}: £${q.price} (${q.warrantyMonths}mo warranty)`;
}

// formatQuote({ device: "iPhone 15", price: "149" });  // Type error. Good.

test yourself

01The event loop lets a server...

02Why does TypeScript help when an AI writes your code?

03Express 5 is to Node.js what ___ is to Python:

the real check

Add a typed feature to a real codebase and run its tests.

0 stamps earned·streak: 0 days

Signed out: progress lives in this browser. to carry it everywhere.

vibe-coder payoff

Reading JS/TS fluently is the difference between 'hope it works' and 'I reviewed it'.