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

himanshuhimanshu
11 min read

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)

  1. Render Phase: React components render JSX, which gets converted to a Virtual DOM tree (a JavaScript object).

  2. Update Phase: When state or props change, React creates a new Virtual DOM tree.

  3. Diffing Phase: React compares the new Virtual DOM with the previous one (this process is called diffing).

  4. 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:

HTMLJSX
classclassName
forhtmlFor
Self-closing tags optionalRequired for empty tags: <img />
Attributes use stringsCan use JS expressions: id={user.id}

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

FeatureReal DOMVirtual DOMShadow DOM
NatureBrowser APIReact/JS libraryBrowser feature
PerformanceSlow (direct updates)Fast (batched updates)Fast (limited scope)
Used ByAll web pagesReact, VueWeb Components
EncapsulationNoNoYes (isolated scope)
Update MechanismDirect DOM manipulationDiffing & patchingNative 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 DOM

  • Improves 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.

0
Subscribe to my newsletter

Read articles from himanshu directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

himanshu
himanshu