How React Virtual DOM Works Under the Hood

When developer first start learning React.js, one of the most confusing terms they hear is Virtual DOM
People often say:
React is fast because of the Virtual DOM
But what actually is the Virtual DOM?
How does it work internally?
Why does React even need it?
In this blog, we will understand the complete flow of how React updates the UI under the hood using very simple language and step-by-step explanations.
The Problem React Wanted to Solve
Before React became popular, developers mainly updated the UI by directly manipulating the browser DOM using JavaScript.
document.getElementById("title").innerText = "Hello";
This works perfectly for small applications. But modern applications contain thousands of elements updating continuously. Notifications appear, chats update, feeds refresh, animations run, and user interactions happen constantly.
The issue is that updating the Real DOM frequently is expensive.
Whenever the browser DOM changes, the browser may need to:
Recalculate styles
Recalculate layouts
Repaint the screen
Re-render parts of the webpage
These operations are computationally costly. If updates happen too frequently, applications become slow and laggy.
React was created to solve this exact problem.
Instead of directly changing the Real DOM every time something updates, React first performs calculations in memory and updates only the necessary parts of the UI.
This idea became the foundation of the Virtual DOM.
What is the DOM?
Dom Stand for Document Object Model.
Whenever a browser loads a webpage, it converts HTML into a tree-like structure.
Example:
<body>
<div>
<h1>Hello</h1>
<button>Click</button>
</div>
</body>
Browser converts this into:
Every HTML element becomes a node inside the DOM tree.
The browser uses this structure to display the webpage on the screen.
The Real DOM is powerful, but modifying it repeatedly is expensive because every change may trigger visual updates in the browser.
What is the Virtual DOM?
The Virtual DOM is a lightweight JavaScript representation of the Real DOM.
Instead of directly updating the browser DOM, React first creates a virtual copy of the UI in memory.
For example:
<h1>Hello React</h1>
Internally becomes something similar to:
{
type: "h1",
props: {
children: "Hello React"
}
}
These JavaScript objects form the Virtual DOM tree.
Because JavaScript operations are fast, React can efficiently create, compare, and update these virtual structures before touching the actual browser DOM.
This is the main reason React performs updates efficiently.
Real DOM vs Virtual DOM
| Real DOM | Virtual DOM |
|---|---|
| Actual browser DOM | Virtual copy in memory |
| Expensive to update | Lightweight and fast |
| Directly affects UI | Does not directly affects UI |
| Browser handles it | React handles it |
| Frequently updates are slow | Comparisons are efficient |
The Virtual DOM is like a rough draft. You make all your edits on the draft first, compare it to the published version, find only the changed sentences, and then update just those sentences in the published version. way faster than reprinting the whole book.
Initial render process in React
When a React application loads for the first time, React performs an initial render.
suppose we have this component:
function App() {
return <h1>Hello React</h1>;
}
The rendering process happens step by step.
First, react reads the component and converts JSX into JavaScript objects. these Object become the Virtual DOM tree.
At this stage, React is only creating a virtual representation inside memory.
After the virtual DOM tree is ready , React converts it into actual browser DOM elements and inserts them into the webpage.
The flow looks like this:
Component
↓
Virtual DOM Created
↓
Real DOM Created
↓
UI Appears on Screen
This process is called the Initial Render.
What Happens When State or Props Change?
React applications are dynamic because data changes continuously.
suppose we have a counter component:
function Counter() {
const [count, setCount] = useState(0);
return <h1>{count}</h1>;
}
Initially , React create a virtual DOM tree representing:
<h1>0</h1>
Now imagine the user clicks a button and state changes:
setCount(1)
Many beginners think React directly updates the browser DOM.
but react actually follows a smarter process.
When state or props changes, React re-runs the components function and create a completely new virtual DOM tree representing the updated UI.
Now React has:
Previous Virtual DOM tree
New Virtual DOM tree
The next step is comparing them.
Creation of a New Virtual DOM Tree
React calls your component function again with the new state value. This produces a new Virtual DOM tree a fresh JavaScript object representing what the UI should look like after the update.
React does not modify the old Virtual DOM tree. It creates an entirely new one. Creating a JavaScript object is incredibly cheap it takes microseconds, not the milliseconds that real DOM updates cost.
What diffing (reconciliation) means
The process of comparing the old Virtual DOM tree with the new virtual DOM tree is called Reconciliation or simply Diffing.
React check each node carefully to understand:
which elements changed
which stayed the same
which were removed
which were added
This comparison helps React determine the smallest possible set of updates required for the UI.
How React Finds Minimal Required Changes
React follows some smart assumptions while comparing trees.
If two elements have different types, React assumes the entire node changed.
Example:
Old:
<h1>Hello</h1>
New:
<p>Hello</p>
Since h1 and p are different elements, React removes the old node and creates a new one.
But if element types are the same, React updates only changed attributes or text.
Example:
old:
<button class="red">
New:
<button class="blue">
React keeps the existing button and changes only the class name. This strategy avoids unnecessary DOM recreation.
Updating Only Changed Nodes in the Real DOM
After React finished comparing both Virtual DOM trees, it create a small list of required updates.
For example:
Update text content
Change attributes
Remove elements
Add new elements
Finally, React applies only those specific changes to the Real DOM
This phase is called the Commit Phase.
Instead of rebuilding the whole webpage, React updates only the changed nodes.
This is why React applications feel smooth and efficient.
Why this approach improves performance
The main performance advantage comes from minimizing expensive browser DOM operations.
React performs most calculations inside JavaScript memory using lightweight Virtual DOM objects.
Instead of blindly updating everything, React intelligently updates only what changed.
this reduces:
Unnecessary DOM manipulation
Layout recalculations
Repainting operations
UI rendering cost
As applications grow larger, this optimization becomes extremely valuable.
High-level overview of React render → diff → commit flow
whenever state or props change in React.js, React follows a simple three-step process to update the UI efficiently, This process is called the Render -> Diff -> Commit flow.
First comes the render phase.
In this step, React runs the component again and create a new virtual DOM tree in memory . React does not touch the real browser DOM yet. it only prepares a new version of the UI based on the updated data.
For example:
function Counter() {
const [count, setCount] = useState(0);
return <h1>{count}</h1>;
}
if count changes from 0 to 1, React create a new virtual DOM showing:
<h1>1</h1>
After that comes the Diff Phase. Here, React compares the old Virtual DOM with the new Virtual DOM. This process is called diffing or reconciliation. React checks what actually changed.
Example:
Old UI:
<h1>0</h1>
New UI:
<h1>1</h1>
React notices that only the text changed, not the whole <h1> element.
Finally comes the Commit Phase. React updates only the changed part inside the Real DOM. Instead of rebuilding the whole page, React changes only the text from 0 to 1.
The complete flow looks like this:
State Changes
↓
Render Phase
(New Virtual DOM Created)
↓
Diff Phase
(Old vs New Compared)
↓
Commit Phase
(Real DOM Updated)
--END--
