Quiz

What is virtual DOM in React?

Topics
React

TL;DR

The "virtual DOM" in React is a tree of plain JavaScript objects (React elements) that describes what the UI should look like — it is not a copy of the actual DOM. When state or props change, React builds a new tree, compares it with the previous one (a process called reconciliation, performed by the Fiber reconciler since React 16), and applies only the necessary changes to the real DOM. The React team now prefers the terms "React elements" and "Fiber tree." The main benefit is the declarative programming model, not raw speed over hand-written DOM updates.


What is virtual DOM in React?

The virtual DOM is the informal name for React's in-memory element descriptions used during rendering and reconciliation.

Introduction

"Virtual DOM" is the term React originally used to describe how it models a UI: instead of application code issuing most DOM instructions directly, components return a tree of React elements describing the desired output. React reconciles that description with the previous one and commits the required DOM changes.

Note that the React team has moved away from the "virtual DOM" label in recent years. Current documentation prefers talking about React elements (the descriptions you return from components) and the Fiber tree (React's internal work-in-progress representation). The mental model is largely the same, but the newer terminology is more accurate: these structures are not a copy of the DOM — they are a separate tree of element descriptions that React uses to decide what to commit to the DOM.

How it works

React turns component output into host changes through the following stages:

  1. Initial rendering: When a React component renders for the first time, it returns a tree of React elements — plain JavaScript objects describing the UI (not a copy of the DOM).
  2. Updating state: When state or props change, the affected components re-render and produce a new element tree.
  3. Reconciliation: React's Fiber reconciler walks the new tree and compares it against the previous one. Fiber represents work in units so eligible concurrent rendering can be paused, resumed, or abandoned, enabling features such as Transitions and Suspense.
  4. Commit: After diffing, React applies only the changes that actually differ to the real DOM in a single commit phase. Effects (useEffect, useLayoutEffect) run at well-defined points around this commit.

Benefits

The abstraction supports declarative updates and renderer-independent component logic, with runtime tradeoffs:

  • Declarative model: You describe what the UI should look like for a given state, and React figures out how to get the DOM there. This is the real selling point — not raw speed.
  • Abstraction: Developers can write code without manually orchestrating DOM mutations, event wiring, or ordering of updates.
  • Explicit output model: Pure components calculate output from props, state, and context, giving each render a traceable set of inputs.
  • Enables concurrent rendering: Because the element/Fiber tree is just data, React can work on an update off to the side, discard it, or prioritize a more urgent one — something that is hard to do when mutating the DOM directly.

A common claim is that "the virtual DOM is faster than the real DOM." The comparison is misleading: React adds reconciliation work, while carefully targeted imperative code can update a known DOM node directly. React's value is a general, predictable way to derive host updates from declarative component output; measure performance for the actual workload.

Example

Here is a simple example to illustrate how the model works:

import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
export default Counter;

When the button is clicked, count updates and Counter re-renders, producing a new tree of React elements. React's reconciler diffs it against the previous tree, sees that only the text content inside <p> changed, and updates just that text node in the real DOM.

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise
Check your understanding Exercise

Which description best defines the “virtual DOM” in React?