Track V
JavaScript engines, under the hood
How V8 turns your source into fast machine code: parsing, Ignition bytecode, the TurboFan JIT and deopt, hidden classes and inline caches, value representation, and generational garbage collection.
- How V8 runs JavaScript: parse, bytecode, JIT
JavaScript is dynamically typed and starts life as text, yet it runs at speeds that ought to be impossible for an interpreted language — and the reason is that a modern engine like V8 is not an interpreter but a pipeline that starts by interpreting cheap bytecode and then compiles only the hot parts to optimized machine code. This lesson builds that tiered pipeline as the frame the whole module hangs on.
12 min - Parsing and the AST: turning text into a tree (lazily)
Before V8 can run a single line of your code it has to turn raw source text into a tree-shaped structure it can actually work with — and the most important thing to know about that step is how hard the engine works to avoid doing it in full, because most functions on a page never run.
12 min - Bytecode and Ignition: the baseline interpreter
The AST that parsing produced still isn't something V8 can run directly — it first gets compiled to compact bytecode for V8's own virtual machine, and that bytecode is what the Ignition interpreter actually executes as every function's very first tier.
12 min - The JIT: speculative optimization and deoptimization
TurboFan compiles hot functions into fast machine code by betting on the types it has observed in Ignition's profiling data, guarding every bet with a cheap runtime check, and deoptimizing back to the interpreter the instant a guard fails — speculation plus deopt is the whole trick.
13 min - Hidden classes and inline caches
A JavaScript object looks like a free-form dictionary, but V8 secretly assigns it a hidden class describing a fixed memory layout and caches every property lookup against that layout, which is the mechanism that lets dynamic objects run at near-struct speed and the reason the order you add properties in actually matters.
13 min - Value representation: Smis, heap numbers, and tagged pointers
A JavaScript variable can hold a small integer one moment and a string the next, yet under the hood it has to be storable in a single machine word — and V8 solves this with tagged pointers, so that small integers live inline for free while everything else is a pointer to the heap.
12 min - Garbage collection: generational, and why pauses cause jank
JavaScript frees memory automatically by reclaiming objects nothing can reach anymore, and V8 does that with a generational collector built around one observation — most objects die young — but because the work runs on the main thread, a badly-timed pause shows up as dropped frames.
13 min - Writing engine-friendly JavaScript
Every optimization in this module rewards the exact same underlying thing — regularity — so a handful of mechanical habits keep your code on the engine's fast paths, but the most important rule of all is to measure first rather than cargo-cult advice against an engine that keeps changing.
13 min