V8 engine internals
V8 parses JS to an AST, generates Ignition bytecode, then tiers up hot code through Sparkplug, Maglev, and TurboFan JITs. Hidden classes and inline caches make property access fast.
V8 is the JavaScript engine inside Chrome, Node, Deno, Cloudflare Workers, and Electron. It is not a single compiler. It is a four-tier system that starts cheap and gets more expensive as code gets hotter.
The pipeline:
- Parse source to AST.
- Ignition (interpreter) generates bytecode and runs it. Cheap to start.
- Sparkplug (baseline JIT) compiles bytecode to unoptimized machine code. Faster execution, almost no compile cost.
- Maglev (mid-tier JIT) generates optimized machine code from feedback collected by Ignition and Sparkplug.
- TurboFan (top-tier JIT) generates highly optimized code for the hottest functions, using speculative assumptions.
If TurboFan's assumptions break (a function it specialized for integers gets a string), the code is deoptimized and execution falls back to a lower tier. Then the function gets re-profiled and may climb back up.
Hidden classes (Shapes)
Objects in JS look like hash maps, but V8 stores them like structs whenever it can. Every object has a hidden class (V8 calls them "Maps," everyone else calls them "Shapes") that records the property layout. Two objects with the same properties added in the same order share a shape.
const a = { x: 1, y: 2 }; // Shape: {x, y}
const b = { x: 3, y: 4 }; // Same shape
const c = { y: 5, x: 6 }; // Different shape! Property order matters.Same shape means property access is one memory load at a known offset. Different shapes means a slower lookup.
Inline caches (ICs)
When V8 sees obj.x, it caches the shape it saw plus the offset of x. Next call: if the shape matches, jump to the offset. This is an inline cache. Functions stay monomorphic (one shape) if you pass them the same object shape every time. Polymorphic (2-4 shapes) is slower. Megamorphic (5+) falls back to a hash lookup.
Practical rules
- Initialize all properties in the constructor in the same order.
- Do not delete properties (it transitions the shape to a "dictionary mode" object that loses ICs).
- Avoid mixing types in arrays. V8 has specialized representations for arrays of small integers, doubles, and objects. A mixed array uses the slow path.
- Avoid
argumentsin optimized code. Use rest parameters.
V8 is fast because it bets on regularity. Write regular code and it runs near C speed. Write chaotic code and you pay for the chaos.
Learn more
- Article
- Article
- ArticleMathias Bynens: V8 internals for JavaScript developersMathias Bynens