Understanding Virtual DOM and JSX in React: The Engine Behind Efficient UI Rendering

React has revolutionized front-end development by making UI creation more declarative, efficient, and component-driven. But what makes React so fast and developer-friendly under the hood?
Two core innovations power React’s performance and simplicity:
The Virtual DOM, which makes UI updates faster and more efficient
JSX, a JavaScript syntax extension that lets you write HTML-like code in your JavaScript files
In this article, we'll break down what the Virtual DOM really is, how it works, and why JSX isn’t just a fancy HTML syntax. Whether you're a beginner learning React or an intermediate developer brushing up your fundamentals, understanding these two concepts is key to writing better, more efficient React apps.
What is the DOM?
Before diving into Virtual DOM, we first need to understand Document Object Manipulation (DOM).
DOM : The Bridge between HTML and JavaScript
The DOM is the programmatic representation of the structure of a web page. Think of it as a tree where each node is element of the page — headings, paragraphs, etc.
When you write HTML like:
<h1> Hello </h1>
The browser parse it and create a node in the DOM tree that you can access and manipulate using JavaScript.
document.querySelector('h1').textContent = 'hello world';
Why traditional DOM is slow?
Imagine you are arranging books vertically by their titles. Whenever you get a book with a title starting with 'A', 'B', or any other letter that you have already arranged, you have to remove the books above it and place the new book in the correct spot. This process increases the time it takes for you to arrange the books.
This is what happens when we add a new element to the DOM or update some elements. The DOM has to rearrange or repaint the entire layout.
Updating the DOM might seem simple, but behind the scenes, it’s expensive in terms of performance. Here's why:
Recalculations: Changing one element may trigger reflow and repaint of the entire layout.
Batching issues: Multiple small updates don’t always get grouped efficiently.
Direct manipulation: Developers have to manage when and how to update UI elements.
As applications grow more interactive and data-driven, manipulating the DOM directly becomes a bottleneck. That’s where React steps in with the Virtual DOM.
What is Virtual DOM?
The Virtual DOM is one of the core features of React — a lightweight, in-memory copy of Real DOM that enables efficient UI rendering and updates.
Definition
The Virtual DOM is a JavaScript representation of the actual DOM. Instead of interacting with the real DOM directly, React uses this virtual copy to determine the most efficient way to update the UI.
Why is Virtual DOM introduced?
Manipulating the Real DOM is very slow. To solve this, React uses Virtual DOM to:
Minimize real DOM interaction
Batch and optimize updates
Improve performance on dynamic, interactive UIs
How it works (At a High Level)
Render Phase: React components render JSX, which gets converted to a Virtual DOM tree (a JavaScript object).
Update Phase: When state or props change, React creates a new Virtual DOM tree.
Diffing Phase: React compares the new Virtual DOM with the previous one (this process is called diffing).
Reconciliation Phase: React calculates the minimal set of changes needed and applies them to the real DOM.
This strategy avoids unnecessary re-renders and makes UI updates smooth.
How the Virtual DOM Works (Step-by-Step with Example)
Now that you know what the Virtual DOM is, let’s break down how it works step-by-step every time your React app updates:
Step-by-Step Breakdown
1. Initial Render
When your app starts, React renders components and creates a Virtual DOM tree using
React.createElement()
or JSX.React then updates the real DOM for the first time based on this Virtual DOM.
2. State or Props Change
When a user interacts with your app (e.g., clicks a button), state or props change.
React re-renders the affected component, generating a new Virtual DOM tree.
3. Diffing Algorithm
React compares the new Virtual DOM tree with the previous one.
It identifies exactly what has changed using its efficient diffing algorithm.
4. Reconciliation
React reconciles differences by generating a list of the minimal real DOM operations required.
Only the updated parts of the DOM are changed, not the whole UI.
Code Example
{ useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
🔁 What Happens When You Click "Increment"?
React re-renders the
Counter
component.A new Virtual DOM tree is created with the updated
count
.React compares the new tree with the old one.
Only the
<h1>
element is updated in the real DOM — not the entire<div>
or<button>
.
Why This Matters
Without the Virtual DOM, you’d have to manually check which elements changed and update them — a process that’s error-prone and slow. React does it for you, fast and efficiently.
What is JSX?
JSX (JavaScript XML) is a syntax extension for JavaScript that looks like HTML — but it’s much more powerful. JSX is what React developers use to describe the structure of the UI.
Why is JSX created?
Before JSX, developers had to create React elements using plain JavaScript like this:
React.createElement('h1', null, 'Hello world!');
This works, but it’s not intuitive — especially when building complex UIs with nested elements.
JSX solves this by providing a declarative, HTML-like syntax directly in JavaScript:
<h1>Hello world!</h1>
Under the hood, this gets compiled back to React.createElement()
by tools like Babel.
JSX made code more readable
Using JSX:
Keeps structure and logic close together
Makes UI easier to visualize
Allows embedding logic directly using
{}
(e.g.,{username}
)
JSX is Not HTML
Even though it looks like HTML, JSX is not the same. There are a few differences:
HTML | JSX |
class | className |
for | htmlFor |
Self-closing tags optional | Required for empty tags: <img /> |
Attributes use strings | Can use JS expressions: id={ user.id } |
JSX is Optional But Recommended
You could write React without JSX, but JSX:
Saves time
Improves code clarity
Reduces bugs when building nested components
How JSX works under the hood
JSX looks like HTML, but React doesn’t understand it directly. JSX must be compiled into plain JavaScript before React can use it. This transformation happens during your build step using tools like Babel.
JSX → React.createElement()
Here’s a simple example:
element = <h1>Hello, world!</h1>;
gets compiled into:
element = React.createElement('h1', null, 'Hello, world!');
This React.createElement()
function returns a plain JavaScript object — a Virtual DOM node.
Structure of a React Element
When JSX compiles, it creates an object like this:
{
type: 'h1',
props: {
children: 'Hello, world!'
}
}
React uses this object to build the Virtual DOM tree in memory.
JSX Can Nest and Compose Elements
Nested JSX like:
<div>
<h1>Welcome</h1>
<p>This is a JSX example</p>
</div>
is transformed into a tree of React elements, forming part of the Virtual DOM.
JSX (Developer writes)
↓
Babel Transpilation
↓
React.createElement()
↓
Virtual DOM Object Tree
↓
React renders to Real DOM
Understanding this transformation helps you:
Debug more effectively
Optimize performance
Appreciate how React bridges the gap between declarative code and DOM rendering
JSX Rules and Best Practices
JSX might look like HTML, but it follows its own rules. Understanding these rules ensures your code is clean, bug-free, and React-friendly.
1. Return a Single Parent Element
In React, a component must return only one parent element. Multiple elements must be wrapped in a container like a <div>
or a React Fragment:
// ❌ Invalid
return (
<h1>Hello</h1>
<p>World</p>
);
// ✅ Valid using Fragment
return (
<>
<h1>Hello</h1>
<p>World</p>
</>
);
2. Use Curly Braces for Expressions
JSX allows embedding any JavaScript expression inside {}
:
const name = 'React';
return <h1>Hello, {name}!</h1>;
But you can’t use control structures like if
or for
directly — use ternaries or map functions instead.
3. Use className
Instead of class
Since class
is a reserved keyword in JavaScript, JSX uses className
for HTML classes:
<div className="container">Hello</div>
Similarly, use htmlFor
instead of for
in <label>
elements.
4. Self-Closing Tags Must Be Closed
In JSX, tags must be explicitly closed:
// ✅ Correct
<img src="logo.png" alt="Logo" />
<br />
5. Avoid Inline Logic in JSX
Keep JSX readable by moving logic out of the return block:
// ❌ Avoid this:
return <h1>{isLoggedIn ? 'Welcome' : 'Please log in'}</h1>;
// ✅ Better:
const greeting = isLoggedIn ? 'Welcome' : 'Please log in';
return <h1>{greeting}</h1>;
6. Use Fragments to Avoid Unnecessary DOM Elements
React Fragments let you group children without adding extra nodes to the DOM:
<>
<Item />
<Item />
</>
Bonus: JSX Is Just JavaScript
Because JSX is compiled to JavaScript, you can:
Store JSX in variables
Pass it as props
Return it from functions
This flexibility makes it very powerful for building dynamic UIs.
Virtual DOM vs Real DOM vs Shadow DOM
These three terms often confuse developers — especially those new to frontend development. Let’s clearly differentiate them.
1. Real DOM (Document Object Model)
This is the actual representation of the webpage displayed in the browser.
Manipulating it directly (via JavaScript or libraries like jQuery) is slow and inefficient — especially for large UIs.
2. Virtual DOM
Introduced by React and similar libraries.
It’s a lightweight JavaScript object that represents the Real DOM.
React creates a Virtual DOM tree, compares it with the previous one, and only updates the real DOM where changes occurred.
This process is called diffing and reconciliation.
Much faster and more efficient than directly modifying the real DOM.
3. Shadow DOM
A browser-native feature used mostly in Web Components.
Allows developers to encapsulate styles and markup, so they don't interfere with the rest of the DOM.
Used in tools like Lit, Stencils, or native web components, not by React directly.
Comparison Table
Feature | Real DOM | Virtual DOM | Shadow DOM |
Nature | Browser API | React/JS library | Browser feature |
Performance | Slow (direct updates) | Fast (batched updates) | Fast (limited scope) |
Used By | All web pages | React, Vue | Web Components |
Encapsulation | No | No | Yes (isolated scope) |
Update Mechanism | Direct DOM manipulation | Diffing & patching | Native browser updates |
Common Misconceptions About Virtual DOM and JSX
Even experienced developers sometimes misunderstand how JSX and the Virtual DOM work. Let’s clear up a few widespread myths.
1. "JSX is HTML"
Reality:
JSX is not HTML — it just looks like it. It’s a syntax extension for JavaScript, and it compiles to React.createElement()
calls.
For example:
<h1>Hello</h1>
is actually:
React.createElement('h1', null, 'Hello')
2. "Virtual DOM Replaces the Real DOM"
Reality:
The Virtual DOM does not replace the Real DOM. It simply acts as an intermediary between React’s rendering logic and the browser’s DOM.
It allows React to compute the most efficient way to update the Real DOM — but the Real DOM still exists and gets updated in the end.
3. "The Virtual DOM is Always Faster"
Reality:
The Virtual DOM helps optimize updates, but it's not magic. In fact, in some edge cases (very frequent updates, animations, etc.), raw DOM manipulation or canvas/WebGL rendering can outperform React.
React offers tools like:
React.memo()
shouldComponentUpdate
useMemo
,useCallback
…to help you manually optimize if needed.
4. "JSX is required to use React"
Reality:
JSX is optional! You can write React code without JSX using React.createElement()
. However, JSX is recommended because it improves readability and development speed.
5. "JSX is a runtime feature"
Reality:
JSX does not run in the browser — it must be compiled by Babel into JavaScript before being executed. That's why you need a build step when working with React apps.
Bottom Line:
JSX is syntactic sugar, not HTML.
The Virtual DOM is an optimization layer, not a replacement.
Use these tools wisely, and you'll build better, faster UIs.
Conclusion
Understanding how React works under the hood — especially the Virtual DOM and JSX — is essential for building efficient and maintainable applications.
Let’s recap:
🔄 Virtual DOM:
A lightweight copy of the real DOM that lives in memory
Enables React to perform efficient, minimal updates to the UI
Works through a diffing and reconciliation process
📝 JSX:
A syntax extension that lets you write HTML-like code in JavaScript
Compiles to
React.createElement()
which builds the Virtual DOMImproves code clarity, readability, and maintainability
Together, Virtual DOM and JSX are the foundation of React’s declarative UI model. They free developers from the complexities of direct DOM manipulation and make it easier to build dynamic, fast, and scalable user interfaces.
Final Thought
While many developers use React without fully understanding what’s happening behind the scenes, diving into the Virtual DOM and JSX will give you a deeper confidence and control over your code. These concepts are not just theory — they directly affect performance, scalability, and developer experience.
Keep learning, experiment with custom components, and try optimizing renders. You’ll soon realize just how powerful React becomes when you truly understand what’s powering it.
Subscribe to my newsletter
Read articles from himanshu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
