Skip to content

JavaScript Engines

A JavaScript engine is a program that executes JavaScript code. It’s the heart of every JavaScript runtime.

Without an engine, your JavaScript code is just text in a file. The engine is what makes it actually do something — it reads your code, understands it, and tells the computer what to do.

flowchart TD
subgraph Engine["💻 JavaScript Engine"]
A["📄 Source Code"] --> B["🔍 Parser"]
B --> C["🌳 AST (Abstract Syntax Tree)"]
C --> D["⚡ Interpreter (Ignition)"]
D --> E["📝 Bytecode"]
E --> F["🚀 Compiler (TurboFan)"]
F --> G["⚙️ Optimized Machine Code"]
end
G --> H["✅ Execution"]
style Engine fill:#1e1e2e,color:#fff
style G fill:#059669,color:#fff
style H fill:#10b981,color:#fff
flowchart LR
A["JavaScript Engines"] --> B["V8"]
A --> C["SpiderMonkey"]
A --> D["JavaScriptCore"]
A --> E["Hermes"]
B --> F["Chrome"]
B --> G["Node.js"]
B --> H["Deno"]
B --> I["Brave"]
B --> J["Electron"]
C --> K["Firefox"]
D --> L["Safari"]
E --> M["React Native"]
style A fill:#7c3aed,color:#fff
style B fill:#f0db4f,color:#000
EngineUsed ByLanguageKey Features
V8Chrome, Node.js, Deno, Brave, ElectronC++Fastest, largest ecosystem
SpiderMonkeyFirefoxC++First JS engine ever (1996)
JavaScriptCoreSafari (WebKit)C++Most power-efficient
HermesReact NativeC++Optimized for mobile startup
ChakraLegacy Edge (pre-Chromium)C++No longer developed
flowchart LR
A["✏️ Source Code"] --> B["🧩 Parser"]
B --> C["🌳 AST"]
C --> D["⚡ Interpreter"]
D --> E["📝 Bytecode"]
D -.->|"Hot code detected"| F["🔥 Compiler"]
F --> G["⚙️ Optimized Code"]
G --> D
style A fill:#fbbf24
style G fill:#34d399
  1. Parsing — Source code → Tokens → Abstract Syntax Tree (AST)
  2. Interpreting — AST → Bytecode (executed quickly)
  3. Profiling — Engine watches which code runs frequently (“hot”)
  4. Compiling — Hot code → Optimized machine code
  5. Deoptimizing — If assumptions break, fall back to interpreted code
StepComponentWhat it does
1ScannerBreaks source into tokens (let, =, 5, ;)
2ParserCreates AST (Abstract Syntax Tree)
3IgnitionInterpreter → generates bytecode
4TurboFanOptimizing compiler → machine code
5OrinocoGarbage collector → frees unused memory

V8 is written in C++ and contains over 1 million lines of code. It was created by Google in 2008 for Chrome. Before V8, JavaScript was slow. V8 made JavaScript fast enough to run server-side (birth of Node.js).

Engines use hidden classes and inline caching to speed up property access:

// V8 creates a hidden class for this object shape
function Point(x, y) {
this.x = x; // Hidden class transition 1
this.y = y; // Hidden class transition 2
}
// Both use the same hidden class → fast
const p1 = new Point(1, 2);
const p2 = new Point(3, 4);
// Different structure → slow (hidden class changes)
p1.z = 5; // Forces new hidden class
  • Write monomorphic code (objects with same shape) for better performance
  • Initialize all properties in the constructor
  • Avoid deleting properties from objects
  • Use Map for dynamic key collections (instead of objects)

Q: “How does V8 execute JavaScript?” A: “V8 uses a multi-tier pipeline: Ignition (interpreter) generates bytecode quickly, while TurboFan (compiler) optimizes hot code paths into native machine code. Hot code refers to functions that run many times.”

  • JavaScript engines convert high-level JS to machine code
  • V8 is the most popular (Chrome, Node.js, Deno)
  • Modern engines use JIT (Just-In-Time) compilation
  • Engines optimize hot code paths for performance
  • Different engines have different trade-offs (speed vs memory)

💡 Key Insight: The engine is just the code executor. The runtime (browser/Node.js) provides all the APIs you actually use (DOM, fetch, console, etc.).