Isolates, Contexts & threads
Everything in the pipeline happens inside a container called an Isolate. To embed V8 (as Chrome, Node, Deno, or workerd do) you create isolates, give them Contexts to run code in, and rely on snapshots to make startup fast. This page covers V8's runtime structure and threading model.
::: info Ubiquitous language Isolate: one isolated VM instance — its own heap, GC, and (logically) single thread of JS execution. Context: a JavaScript global environment (global object + builtins). Snapshot: a serialized pre-built heap, deserialized to boot quickly. :::
Isolate: one VM, one heap
class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
public:
Heap* heap() { return &heap_; }
…
};
— src/execution/isolate.h#L562-L571
An Isolate owns its heap and all the VM state (the roots, the string table, the builtins, the tiering manager). Two isolates share nothing by default — objects from one cannot reference objects in another. This isolation is what lets a browser run many independent JS environments (tabs, workers) in one process without them interfering.
Threading model
JavaScript execution in an isolate is single-threaded: at most one thread runs JS in a given isolate at a time. That assumption simplifies enormous amounts of the engine (object headers, IC updates, allocation fast paths). V8 does use many background threads — for concurrent marking, parallel scavenging, background compilation, and concurrent optimization — but those are carefully coordinated helpers, not concurrent mutators of the JS heap. To run JS on multiple threads you use multiple isolates (e.g. Web Workers), communicating by copying or via shared array buffers.
Contexts
A Context is a heap object representing a JS execution environment. The special
NativeContext holds the global object plus all the built-in machinery —
Array, Object, Function, the prototypes, the well-known Maps, hundreds of
internal functions:
// [ extension ] … For native contexts, it contains the global object.
V8_OBJECT class Context : public HeapObject { … };
class NativeContext : public Context { … };
— src/objects/contexts.h#L499-L549
One isolate can hold many contexts (each <iframe> in a page, each vm.createContext()
in Node). They share the isolate's heap but each has its own globals — which is why
an array from one frame is not instanceof Array of another frame (different
Array constructors live in different native contexts).
Snapshots
Initializing a fresh isolate — creating all those builtins, prototypes, and Maps by running the bootstrap code — is slow. So V8 does it once, at build time, and serializes the resulting heap into a snapshot blob that each isolate deserializes at startup:
class Snapshot : public AllStatic {
static bool Initialize(Isolate* isolate); // boot from snapshot
static MaybeDirectHandle<Context> NewContextFromSnapshot(…); // fast new context
};
— src/snapshot/snapshot.h#L25-L120
The startup snapshot restores the isolate's base heap and builtins.
Context snapshots let
NewContextFromSnapshotcreate a fresh global environment by copying, instead of re-running setup.Embedders can build custom snapshots (via
mksnapshot/SnapshotCreator) that include their own pre-initialized objects — Node and Chrome both do this to shave startup time.
::: tip Why this is a big deal for startup Deserializing a contiguous blob into the heap is far cheaper than executing thousands of lines of bootstrap JS/C++. Snapshotting turns "construct the standard library" from a runtime cost paid on every launch into a one-time build cost. It is one of the most effective startup optimizations in the engine, and a technique worth copying in any runtime with expensive initialization. :::
How embedders see it
Process
├─ Isolate A
│ ├─ Heap (Orinoco)
│ ├─ Context 1 (globals + builtins)
│ └─ Context 2 (separate globals, same heap)
└─ Isolate B (Worker — fully independent heap)
The public C++ API (v8::Isolate, v8::Context, v8::Local<T>) mirrors these
internal structures; Local<T> is the embedder-facing
handle.
See also
The big picture — what runs inside the isolate.
Builtins & Torque — what the native context is full of.
GC overview — the heap the isolate owns.
The V8 sandbox — isolating that heap from the process.