The virtual DOM and reconciliation
React's central trick is that you never tell it to change the DOM — you describe what the UI should look like right now as a tree of plain objects, and React compares that description against the previous one and works out the minimal set of real DOM mutations itself. This lesson builds that model, dispels the myth that the virtual DOM is magically fast, and frames everything the rest of the module opens up.
The virtual DOM and reconciliation
If you've only ever used React from the outside — writing components, calling useState, watching the screen update — the machine underneath can feel like magic: you change a variable and the right pixels change, without you ever touching the DOM. It isn't magic, and the core idea is smaller than the mystique around it. Once you see it, the whole rest of React (JSX, keys, fiber, hooks, the rules about them) turns into consequences of one design decision.
The decision, in one sentence: instead of imperatively mutating the DOM, you give React a description of what the UI should look like for the current state — a tree of plain JavaScript objects — and React compares that description to the previous one and figures out the minimal DOM changes needed to match. That description is the "virtual DOM," and the comparison-and-apply process is "reconciliation." Everything below unpacks that.
Imperative vs declarative, concretely
Without React, updating a UI is imperative: you find the node and mutate it. To keep a counter's text in sync you write "set this element's text to the new count," by hand, everywhere the count can change. The bugs live in the gaps — the update you forgot, the two pieces of state that drifted out of sync, the DOM node you mutated in the wrong order. You are responsible for every transition between states.
React makes it declarative: you write a function that, given the current state, returns what the UI should be — not the steps to get there, just the destination. count is 5, so the component returns "a div containing the text 'Count: 5'." You never write "change the text from 4 to 5." You describe the target for 5, and React's job is to make the real DOM match that target, whatever it currently is. You describe what, React computes the how.
For that to work, React needs two things: a cheap way to represent "what the UI should be," and a way to turn a new description into real DOM changes. Those are the virtual DOM and reconciliation.
The virtual DOM is just a tree of plain objects
When your component runs, it returns React elements — and an element is nothing but a small plain object describing a node: its type ('div', or a component function), its props, and its children. A whole UI is a tree of these objects. That tree is the "virtual DOM": a lightweight, in-memory description of the UI, completely separate from the real DOM. Creating it is cheap — it's just allocating objects, no browser layout or painting involved. (Elements and JSX takes the element apart.)
The key move: every time state changes, your components run again and produce a brand-new virtual tree describing what the UI should be now. React now holds two trees — the one it rendered last time, and the new one — and the question becomes: what real DOM operations turn the old into the new?
Reconciliation: diff the trees, apply the difference
Answering that question is reconciliation. React walks the new element tree and the previous one in parallel, comparing node by node, and works out the difference: this text changed, that attribute changed, this child was added, that subtree was removed. Then — and only then — it performs exactly those mutations on the real DOM. Nodes that didn't change are left untouched.
This is the loop at the heart of React: state change → re-render to a new virtual tree → reconcile against the old tree → commit the minimal DOM changes. You supplied only the "what should the UI be" function; React supplied the diffing and the surgical DOM updates. The reason you can get away with re-describing the entire UI on every state change — which sounds absurdly wasteful — is that describing it is cheap (plain objects) and React only touches the DOM for the parts that actually differ.
The myth to kill right now: the virtual DOM is not "fast"
Here is the most important correction in this lesson, because it's the most widely repeated myth. People say "React is fast because of the virtual DOM." That is misleading. Diffing two trees and then mutating the DOM is more work than a perfectly-targeted hand-written DOM update — an expert doing the minimal imperative mutation directly will always beat React's diff-then-patch on raw speed. The virtual DOM does not make updates faster than the theoretical best.
What it actually buys you is a declarative programming model with acceptable, automatic performance. You get to write "describe the UI for this state" — simple, less bug-prone, composable — and React makes the resulting updates good enough by never doing more DOM work than the diff requires. The win is developer model plus a reasonable performance floor, not raw speed. Internalize that and you'll reason about React correctly: the goal of everything ahead (the diff heuristics, fiber, memoization) is to keep that automatic performance good enough as apps grow — not to chase a speed crown the virtual DOM was never going to win.
What this opens up
Every remaining lesson in this module is a zoom-in on one part of that loop:
- What exactly is in the tree? Elements, components, and JSX — how JSX becomes element objects and how components compose them.
- How does the diff actually work, cheaply? The diffing algorithm — the heuristics that make reconciliation O(n) instead of impossibly expensive, and why lists need keys.
- What data structure does React reconcile over? Fiber — the tree of fiber nodes that makes reconciliation interruptible.
- When does it touch the DOM? Render and commit phases — the split between computing changes and applying them.
- Where does state live across re-renders? Hooks — state as a linked list hanging off each fiber.
- How does it stay responsive? Scheduling and concurrent React — yielding to the browser between chunks of reconciliation, which ties straight back to the event loop and the frame budget.
And it connects to the platform modules directly: the DOM mutations React commits go through the rendering engine's reflow/repaint pipeline, and React's scheduler exists precisely to avoid blocking the event loop. React is an application of everything under it.
Where this goes next
Before the diffing and the fiber tree, we should be precise about the thing being diffed. Elements, components, and JSX takes apart the humble React element — what JSX actually compiles to, why an element is "just data," and how components (functions that return elements) compose into the tree that reconciliation walks.
Go deeper
- React docs — Preserving and Resetting State — How reconciliation's tree-matching determines when state is kept vs thrown away — the user-facing consequence of this lesson's diff model.
- React (legacy docs) — Reconciliation — React's own explanation of the diffing model and the heuristics the next lesson formalizes.
- Rich Harris — Virtual DOM is pure overhead — The counter-argument that sharpens exactly what the virtual DOM does and doesn't buy you — useful for holding the myth-correction precisely.
Check yourself
Answer out loud, as if an interviewer asked. If you hand-wave, reread that section.
- Contrast imperative and declarative UI updates with a concrete example. What is React's core promise in one sentence?
- What is a React element, physically? Why is producing a whole new virtual tree on every state change not as wasteful as it sounds?
- Define reconciliation. What does React do with the two trees it holds, and what does it ultimately apply to the real DOM?
- State the loop at the heart of React (state → … → DOM) in four steps.
- Correct the myth 'the virtual DOM makes React fast.' What does the virtual DOM actually buy you, if not raw speed?
- If some frameworks deliver the same declarative model without a virtual DOM, what does that tell you about what React's 'essence' really is?
- Name two other lessons in this module and say which part of the state → render → reconcile → commit loop each one zooms into.