Understanding React Internals (Part 1): From the Browser to React — Why React Exists
“I had been using React for over two years. I knew hooks, state management, API calls, routing, and even performance optimizations. But one question kept bothering me: What actually happens inside React when I write
<App />?That question took me on a journey that started not with React — but with the browser itself.”
Most developers learn React by building projects. We learn useState, useEffect, routing, Redux, Context API, and eventually become comfortable building applications.
But very few of us stop and ask:
- What problem was React actually trying to solve?
- Why do we even need a Virtual DOM?
- Why can’t browsers understand JSX?
- What happens after I call
setState()? - Why is React considered declarative?
I realized that I couldn’t answer these questions confidently. I understood how to use React, but not why it worked the way it did.
So I decided to start from the very beginning.
Not from React.
From the browser.
Because before understanding React, we first need to understand the environment React runs in.
It All Starts with the Browser
Every React application eventually runs inside a web browser.
No matter whether you’re using React, Vue, Angular, or plain JavaScript, the browser is responsible for displaying everything on the screen.
Let’s start with something simple.
<h1>Hello, React!</h1>At first glance, this looks like something the browser can directly display.
But that’s not actually what happens.
To the browser, HTML is just a text file.
The browser cannot efficiently manipulate plain text every time something changes. Imagine searching through thousands of lines of HTML every time you wanted to update a single element — it would be extremely inefficient.
Instead, the browser first parses the HTML.
HTML
↓
HTML Parser
↓
DOM TreeThis is where the HTML Parser comes in.
Its job is to read the HTML document and convert it into an internal object structure that JavaScript can interact with.
That structure is called the Document Object Model (DOM).
Understanding the DOM
The DOM is the browser’s in-memory representation of your HTML document.
Instead of treating your webpage as plain text, the browser represents it as a tree of JavaScript objects.
For example,
<body>
<div>
<h1>Hello</h1>
<p>Welcome</p>
</div>
</body>becomes something conceptually like this:
Document
│
HTML
│
BODY
│
DIV
/ \
H1 PEach element becomes a node in this tree.
Because the DOM exists in memory, JavaScript can easily access and modify it.
For example:
document.querySelector("h1").textContent = "Hello, World!";The browser immediately knows which object needs to change.
This is much more efficient than searching through the original HTML file every time.
What Happens After the DOM Changes?
Many developers think changing the DOM immediately changes what’s displayed on the screen.
Not exactly.
Changing the DOM is only the beginning.
Whenever the DOM or CSS changes, the browser performs a series of rendering steps before the user actually sees the update.
This process is called the Browser Rendering Pipeline.
DOM
↓
CSSOM
↓
Render Tree
↓
Layout
↓
Paint
↓
CompositeLet’s briefly understand each stage.
DOM
The browser converts HTML into a tree of objects.
CSSOM
CSS is also parsed into another object structure called the CSS Object Model (CSSOM).
Render Tree
The browser combines the DOM and CSSOM to determine which elements are actually visible on the page.
Layout
The browser calculates the size and position of every visible element.
Paint
The browser draws text, colours, borders, backgrounds, and images.
Composite
Finally, the browser combines everything and displays the completed frame on your screen.
Get Ravi S’s stories in your inbox
Join Medium for free to get updates from this writer.
Only after all these steps does the user see the updated UI.
Is the DOM Slow?
One of the biggest misconceptions I had while learning React was this:
“React exists because the DOM is slow.”
That statement isn’t really accurate.
The DOM itself is highly optimized by modern browsers.
The expensive part is what often comes after a DOM update.
Changing the DOM may force the browser to recalculate layouts, repaint pixels, and composite layers before displaying the new frame.
For example,
document.getElementById("title").textContent = "Hello";looks like a tiny operation.
But depending on what changed, the browser may need to go through parts of the rendering pipeline again.
This becomes more noticeable as applications become larger and updates become more frequent.
Life Before React
Before React became popular, developers primarily built dynamic applications using Vanilla JavaScript or libraries like jQuery.
Imagine building a simple profile page.
When the user updates their name, you might write something like this:
document.getElementById("username").textContent = user.name;
document.getElementById("profile-image").src = user.image;
document.getElementById("email").textContent = user.email;This works perfectly for small applications.
But as applications grow, dozens or even hundreds of UI elements depend on application state.
Whenever the state changes, developers must remember exactly which DOM elements need updating.
Miss one update, and the UI becomes inconsistent with the actual data.
The browser wasn’t the problem.
Keeping the UI synchronized with changing application state was.
Imperative vs Declarative Programming
This is exactly where React changed the way we build user interfaces.
Traditional DOM manipulation is imperative.
You tell the browser how to update the interface.
document.getElementById("title").textContent = "React";
document.getElementById("title").style.color = "blue";You’re responsible for every single step.
React follows a different philosophy.
It is declarative.
Instead of telling React how to update the UI, you simply describe what the UI should look like.
<h1>{title}</h1>Now imagine title changes.
You don’t manually update the DOM.
You simply update the state.
React figures out everything else.
This small shift completely changes how we think about building applications.
Instead of writing instructions for the browser, we describe the desired UI based on the current state.
React takes responsibility for synchronizing the interface.
The Core Philosophy of React
After learning all of this, I realised something that completely changed the way I think about React.
React wasn’t created to make the browser faster.
It wasn’t created because the DOM was “slow.”
It was created because building complex user interfaces by manually synchronizing the DOM with application state doesn’t scale well.
That’s the real problem React solves.
If I had to summarise React in one sentence, it would be this:
React’s primary goal is to keep the UI synchronized with application state while efficiently updating the browser only where necessary.
Once I understood this idea, every other React concept started making much more sense.
Questions like:
- Why do we need JSX?
- What does Babel actually do?
- Why does React create React Elements?
- Why does the Virtual DOM exist?
all naturally followed from this single philosophy.
And that’s exactly where we’ll continue in Part 2, where we’ll trace the journey from JSX to the Virtual DOM and uncover what really happens before your UI appears on the screen.
Thanks for reading! If this article helped you understand why React exists — not just how to use it — consider following the series. In Part 2, we’ll explore JSX, Babel, React Elements, the Virtual DOM, and how React decides what needs to change before updating the browser.








