Skip to main content

Command Palette

Search for a command to run...

How React Virtual DOM Works Under the Hood

Updated
8 min read
How React Virtual DOM Works Under the Hood
A

I’m Arjun Saxena, a passionate software developer specializing in web engineering. I believe in writing code that creates real solutions to real problems. I love building efficient, user-friendly applications and constantly push myself to learn new technologies. Beyond coding, I enjoy sharing knowledge and growing together with others in the tech community.

React is one of the most popular JavaScript libraries for building modern user interfaces. One of the biggest reasons behind React’s performance is the Virtual DOM.

But what exactly is the Virtual DOM? How does React update the UI so efficiently? And what actually happens when state or props change?

In this article, we will understand the complete mental model of how React Virtual DOM works behind the scenes step by step.

What is DOM?

DOM stands for Document Object Model.

When the browser loads an HTML document, it creates a tree-like structure of all HTML elements. This structure is called the DOM.

The DOM represents the webpage you see inside the browser.

JavaScript can access the DOM to dynamically change:

  • Content

  • Structure

  • Styles

Example

<body>
  <h1>Hello</h1>
  <button>Click</button>
</body>

The browser internally creates a tree structure like this:

body
 ├── h1
 │    └── "Hello"
 └── button
      └── "Click"

Problems with Traditional DOM Manipulation

Updating the Real DOM is expensive.

At first, DOM manipulation may look simple:

document.getElementById("title").innerText = "Hi"

But internally, the browser has to do several expensive operations such as:

  • Recalculating layout

  • Repainting the page

  • Reflowing elements

The real problem appears in large applications like:

  • Amazon

  • Flipkart

  • Instagram

  • Facebook

Imagine a page with:

  • 1000 products

  • Search filters

  • Buttons

  • Animations

  • Live updates

Now suppose the user clicks a single like button.

Without optimization, unnecessary DOM updates can:

  • Degrade performance

  • Cause UI lag

  • Trigger unnecessary rendering

Before React, developers manually handled DOM updates:

  • What should update?

  • Where should it update?

  • How much should update?

React simplified this entire process.

What is Virtual DOM?

Virtual DOM is a lightweight JavaScript Object representation of the Real DOM.

Instead of directly updating the browser DOM every time, React first updates the Virtual DOM.

Because the Virtual DOM is made of simple JavaScript objects, it is much faster to compare and manipulate.

The Virtual DOM is an internal React system. It is not directly visible inside the browser.

What Problem Does the Virtual DOM Solve?

The main goal of the Virtual DOM is:

✅ Avoid unnecessary updates in the Real DOM.

React updates only the changed parts of the UI instead of rebuilding the entire page.

Example

Initial UI:

<h1> count : 0 </h1>

React creates a Virtual DOM tree.

Now suppose the user clicks a button and the count changes.

Updated UI:

<h1> count : 1 </h1>

React creates a new Virtual DOM tree.

Then React compares:

  • Old Virtual DOM

  • New Virtual DOM

React detects that only the text changed:

0 -> 1

Instead of rebuilding the entire page, React updates only the changed text node.

🔥 This is why React feels fast and efficient.

Real DOM vs Virtual DOM Table

Feature Real DOM Virtual DOM
Definition Actual browser DOM JS copy of DOM
Speed Slow updates Fast comparisons
Update Cost Expensive Cheap
Rendering Browser directly render karta hai Direct render nahi hota
Manipulation Directly browser pe hoti hai JS memory mein hoti hai
Performance Large apps mein slower Optimized updates
Re-render Entire tree affect ho sakta hai Only changed nodes update
Used By Browser React

Visual Flow

Initial Render Process in React

What is Initial Render?

Initial render means:

The first time a component appears on the screen.

Step 1 — React App Starts

ReactDOM.createRoot(document.getElementById("root")).render(<App />)

React renders the App component inside:

<div id="root"></div>

Step 2 — Component Function Executes

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <button>Click</button>
    </div>
  )
}

The component function executes and returns JSX.

Step 3 — Babel Converts JSX

JSX :

<h1>Hello</h1>

Converted by Babel:

React.createElement("h1", null, "Hello")

Step 4 — Virtual DOM Tree is Created

{
  type: "div",
  props: {
    children: [
      {
        type: "h1",
        props: {
          children: "Hello"
        }
      }
    ]
  }
}

Step 5 — Real DOM Nodes are Created

<div>
  <h1>Hello</h1>
  <button>Click</button>
</div>

Step 6 — DOM is Attached to Root

React attaches the created DOM inside:

<div id="root"></div>

After this, the browser:

  • Calculates layout

  • Paints the screen

  • Displays the UI

How State or Props Change Triggers Re-render

What is Re-render?

Re-render means:

The component function executes again.

Initial render happens for the first time. When the component runs again after updates, it is called a re-render.

State Change Example

function Counter() {
  const [count, setCount] = useState(0)

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  )
}

Re-render Process

Step 1 — Initial Render

The component renders with:

count = 0

Step 2 — User Clicks the Button

setCount(count + 1)

Step 3 — React Updates State

React updates the state internally and schedules a re-render.

Step 4 — New Virtual DOM is Created

The component function executes again.

Step 5 — React Compares Old and New Virtual DOM

React checks what changed.

Step 6 — Real DOM Updates

Only the changed part of the UI updates.

How Does React Know When to Update the UI?

React provides special state functions such as:

setCount()

These functions internally notify React that:

State has changed

The same idea also works with props.

Creation of a New Virtual DOM Tree

Whenever state or props change, React creates a new Virtual DOM tree.

Example:

Old UI:

<h1>Hello</h1>

Old Virtual DOM:

{
  type: "h1",
  children: "Hello"
}

After update:

<h1>Hello Arjun</h1>

New Virtual DOM:

{
  type: "h1",
  children: "Hello Arjun"
}

React now has:

  • Old Virtual DOM

  • New Virtual DOM

These two trees are compared during the diffing process.

What is Diffing and Reconciliation?

Diffing

Diffing is the process where React compares:

  • Old Virtual DOM

  • New Virtual DOM

The goal is to find what changed.

Example

Old :

<h1>Hello</h1>

New :

<h1>Hello Arjun</h1>

React detects :

Only text changed

Reconciliation

Reconciliation is the process where React efficiently updates the Real DOM after diffing.

Instead of replacing the whole <h1> element, React updates only the text.

⚠️ Important:

Diffing finds the changes. Reconciliation applies those changes efficiently in the Real DOM.

How React Finds Minimal Required Changes

React tries to perform the minimum possible DOM operations.

Example 1 — Text Change

Old UI:

<h1>Hello</h1>

New UI:

<h1>Hello Arjun</h1>

React detects :

Only text changed

So React updates only the text node instead of replacing the entire <h1>.

Example 2 — Element Type Changed

Old :

<h1>Hello</h1>

New :

<p>Hello</p>

Now the element type changed:

h1 -> p

In this case, React :

❌ Removes the old <h1> ✅ Creates a new <p>

Because both element types are different.

Updating Only Changed Nodes in the Real DOM

React does not re-render the entire Real DOM.

Instead, React updates only the changed parts.

Example

Old UI:

<h1>Hello</h1>

New UI:

<h1>Hello Arjun</h1>

React updates:

Hello -> Hello Arjun

Only the text node changes.

The entire page is not rebuilt.

🔥 This is one of the biggest reasons behind React’s performance.

Why This Approach Improves Performance

The Real DOM is expensive to update frequently.

Browser DOM updates involve:

  • Layout calculation

  • Repainting

  • Reflow

These operations can become slow in large applications.

React improves performance by:

✅ Creating lightweight Virtual DOM trees

✅ Comparing old and new Virtual DOM trees in memory

✅ Finding minimal changes

✅ Updating only the changed parts in the Real DOM

This reduces unnecessary browser work and makes UI updates faster.

React Render → Diff → Commit Flow

React follows a simple rendering pipeline:

State/Props Change
        ↓
Render Phase
(Create New Virtual DOM)
        ↓
Diff Phase
(Compare Old vs New Virtual DOM)
        ↓
Commit Phase
(Update Real DOM)
        ↓
Browser Paint

Render Phase

React executes components and creates a new Virtual DOM tree.

Diff Phase

React compares the old and new Virtual DOM trees.

Commit Phase

React updates the Real DOM with only the necessary changes.

Finally, the browser paints the updated UI on the screen.