How React Virtual DOM works under the Hood
If you have started learning React, you have probably heard this sentence many times:
“React uses a Virtual DOM to make updates faster.”
But most beginners only memorize this line without actually understanding what it means internally. Questions usually come up like:
What exactly is the Virtual DOM?
Why did React create it?
What problem does it solve?
What actually happens when state changes?
How does React know what to update?
In this article, we will understand the complete flow of React Virtual DOM in the simplest possible way. We are not going deep into advanced internals like Fiber architecture. Instead, we will focus on the mental model that every React developer should clearly understand.
By the end of this article, you will understand how React efficiently updates the UI without unnecessarily rebuilding the entire webpage.
The Problem React Wanted to Solve
Before React existed, developers mainly used direct DOM manipulation using vanilla JavaScript or libraries like jQuery.
For example:
document.getElementById("title").innerText = "Hello";
At first, this looks simple. But as applications become bigger, managing the UI manually becomes difficult and slow.
Imagine applications like: Instagram, Facebook, YouTube, WhatsApp Web. These apps constantly update the screen: Notifications appear, Messages update, Likes increase, Comments load, Videos change, Chats refresh
If every small change directly manipulated the browser DOM repeatedly, performance would become a huge problem.
That is where React introduced a smarter approach.
Understanding the Real DOM
To understand the Virtual DOM properly, you first need to understand the Real DOM. DOM stands for: Document Object Model. The browser converts HTML into a tree-like structure called the DOM tree.
For example:
<body>
<div>
<h1>Hello</h1>
<button>Click</button>
</div>
</body>
The browser internally represents it like a tree: body
body
└── div
├── h1
└── button
This structure is called the Real DOM because it actually exists inside the browser. The browser uses this DOM to display the webpage on the screen.
Why Real DOM Updates Are Expensive
Many beginners think changing text in the DOM is a tiny operation. But internally, the browser may need to do many expensive tasks after a DOM update.
These include:
Recalculating CSS styles
Recalculating layouts
Repainting pixels
Re-rendering parts of the UI
If updates happen frequently, these operations become costly. For small websites, this is manageable. But for large applications with thousands of UI elements updating continuously, direct DOM manipulation becomes inefficient.
React was created to reduce unnecessary DOM updates.
What is the Virtual DOM?
The Virtual DOM is a lightweight JavaScript representation of the Real DOM. Instead of directly changing the browser DOM every time something changes, React first updates this virtual version.
You can think of the Virtual DOM as: A copy of the UI stored in JavaScript memory.
It is not visible on the screen. It is simply an object representation created by React.
For example, this JSX:
<h1>Hello</h1>
Can conceptually become something like:
{
type: "h1",
props: {
children: "Hello"
}
}
This object is much faster to create and compare than directly updating the browser DOM.
Real DOM vs Virtual DOM
Now let us clearly compare both.
| Real DOM | Virtual DOM |
|---|---|
| Actual browser DOM | JavaScript representation |
| Slow to update frequently | Fast to update |
| Final rendering | Planning changes |
| Causes browser rendering work | Exists only in memory |
The key thing to understand is:
React does not avoid the Real DOM completely.
Eventually, the Real DOM must still update because that is what users actually see.
React simply makes the update process smarter and more efficient.
Initial Render Process in React
Now let us understand what happens when a React component renders for the first time.
Consider this component:
function App() {
return <h1>Hello World</h1>;
}
When React runs this component, several things happen internally.
Step 1: React Creates the Virtual DOM Tree
React first converts the component into a Virtual DOM object structure. Conceptually:
{
type: "h1",
props: {
children: "Hello World"
}
}
This becomes React’s internal representation of the UI.
Step 2: React Creates Real DOM Nodes
React now converts the Virtual DOM into actual browser DOM elements.
So React creates:
<h1>Hello World</h1>
inside the browser.
Step 3: Browser Paints the UI
Finally, the browser displays the UI on the screen.
The user now sees:
Hello World
This entire process is called the initial render.
What Happens When State or Props Change?
Now comes the most important part.
Consider this counter example:
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Initially
count = 0
The screen shows: 0
Now the user clicks the button. This line runs:
setCount(count + 1)
At this moment, React knows: “The UI may need to change.”
React Does NOT Immediately Update the Real DOM
This is one of the biggest misconceptions beginners have. Many people think React directly changes the browser DOM immediately after state changes. That is not what happens.
Instead, React creates an entirely new Virtual DOM tree.
Creation of a New Virtual DOM Tree
Before clicking:
<h1>0</h1>
After clicking:
<h1>1</h1>
React now has:
Old Virtual DOM
New Virtual DOM
The next step is comparing them. This comparison process is where React becomes powerful.
What is Diffing (Reconciliation)?
React now compares the old Virtual DOM tree with the new Virtual DOM tree. This process is called: Reconciliation Or commonly: Diffing The goal is simple:
"Find exactly what changed."
React does not blindly rebuild the entire UI. Instead, it intelligently checks differences between the two trees.
Example of Diffing
Old Virtual DOM:
<h1>0</h1>
New Virtual DOM:
<h1>1</h1>
React notices:
The
<h1>element is still the sameOnly the text content changed
So React updates only the text node instead of recreating the entire structure. This is extremely efficient.
How React Finds Minimal Required Changes
React uses a few smart assumptions while comparing trees.
1) Different Element Types Replace Entire Nodes
Example:
Old:
<h1>Hello</h1>
New:
<p>Hello</p>
Since the element type changed from h1 to p, React removes the old node completely and creates a new one.
2) Same Element Type Updates Only Changed Attributes
Example:
Old:
<h1 class="red">Hello</h1>
New:
<h1 class="blue">Hello</h1>
React keeps the same element and only updates the class attribute. This avoids unnecessary DOM operations.
3) Lists Use Keys for Efficient Tracking
When rendering lists, React needs a way to identify items correctly.
Example:
items.map(item => (
<li key={item.id}>{item.name}</li>
))
The key helps React understand:
Which items were added
Which items were removed\
Which items moved
Without keys, React may perform unnecessary updates.
Updating Only Changed Nodes in the Real DOM
After React finishes comparing the trees, it updates only the required parts of the Real DOM.
Instead of doing this
Delete everything
Create everything again
React does this
Update only the changed node
This small optimization makes a huge difference in large applications.
Why This Approach Improves Performance
The biggest performance gain comes from reducing expensive Real DOM operations. React performs most work inside JavaScript memory using the Virtual DOM, which is much faster. Then React applies only minimal changes to the actual browser DOM.
This reduces:
Layout recalculations
Repainting
Unnecessary rendering work
As a result, applications feel faster and smoother.
High-Level React Render → Diff → Commit Flow
Now let us connect everything together into one complete flow.
- Render Phase:
React creates the Virtual DOM tree based on components and state.
Component → Virtual DOM
- Diff Phase (Reconciliation)
React compares:
Old Virtual DOM vs New Virtual DOM
It identifies exactly what changed.
- Commit Phase
React updates only the necessary parts of the Real DOM.
Minimal Real DOM updates happen
Finally, the browser updates the screen.
Complete Lifecycle Example
Let us summarize the entire process step by step.
Initial Render
Component Created
↓
Virtual DOM Created
↓
Real DOM Created
↓
UI Displayed
State Update
State Changes
↓
New Virtual DOM Created
↓
Old and New Trees Compared
↓
Differences Found
↓
Minimal DOM Updates Applied
↓
Browser Updates UI
This is the core working principle of React.
The Biggest Advantage of React
React allows developers to focus on describing UI instead of manually updating the DOM. In vanilla JavaScript, developers manually manipulate elements. In React, developers simply update state.
React handles:
Comparison
Optimization
Efficient DOM updates
This makes development easier and applications more maintainable.
Final Mental Model
If you remember only one thing from this article, remember this: React does not directly update the browser DOM every time state changes. Instead, React follows this process:
1. Create Virtual DOM
2. Create New Virtual DOM after updates
3. Compare old vs new trees
4. Find minimal changes
5. Update only necessary Real DOM nodes
That is the heart of React’s Virtual DOM system.
Conclusion
The Virtual DOM exists to solve the problem of expensive direct DOM manipulation.
React improves performance by:
Creating lightweight Virtual DOM trees
Comparing old and new versions
Finding minimal differences
Updating only required parts of the Real DOM
This makes React applications faster, cleaner, and easier to build.
Most importantly, React gives developers a simpler mental model:
You describe what the UI should look like based on state, and React efficiently handles the updates behind the scenes.
