Chapter 135·Beginner·9 min read
The DOM: How the Browser Models a Page
How the browser turns HTML text into the DOM — a live tree of objects that represents the page. What nodes and the tree really are, how parsing builds them, why the DOM is not your HTML file, and how JavaScript reads and rewrites the page through it.
July 24, 2026
In the overview we saw the browser's pipeline turn text into pixels, and named its very first transformation: HTML becomes the DOM. That step is so foundational that everything afterwards — styling, layout, paint, and every line of JavaScript you'll ever write against a page — operates on the structure it produces. So before we go any further, we need to really understand what the DOM is. Spoiler: it is not your HTML file, and seeing why is the moment the browser stops being magic.
From tags to a tree
HTML is written as nested tags — an element inside an element inside an element. The browser reads that nesting and builds a matching tree: a hierarchy of objects where each element becomes a node, and containment in your markup becomes parent-and-child in the tree. Take this snippet:
<body>
<h1>Hello</h1>
<p>A <strong>tiny</strong> page.</p>
</body>The browser parses it into a tree that looks like this:
body is the parent; h1 and p are its children; strong is a child of p. The words "Hello", "A", "tiny", and "page." are text nodes hanging off their respective elements. That tree — this exact structure of objects, in memory — is the DOM, the Document Object Model. It is the browser's authoritative model of your page, and rendering happens from it, not from your original text.
Everything is a node
The tree is built from nodes, and it's worth knowing there's more than one kind. The main players:
| Node type | What it is | Example |
|---|---|---|
| Element node | An HTML element | <p>, <div>, <button> |
| Text node | The text inside an element | the "Hello" in <h1>Hello</h1> |
| Attribute | A property on an element | class="hero", href="/" |
| Comment node | An HTML comment | <!-- note --> |
| Document | The root of the whole tree | document |
At the very top sits the document node — the entry point your JavaScript reaches for constantly (document.querySelector, document.body). Everything on the page descends from it. When people say "the DOM," they mean this whole rooted tree of nodes, with document at the crown.
The DOM is not your HTML file
This is the single most important idea in the chapter, and the one that clears up the most confusion. Your .html file is static text — the browser downloads it once, and that's the last anyone hears from it. From that text the browser builds the DOM, a live, in-memory model. The two start out equivalent, then immediately diverge, in two ways.
First, the parser repairs and normalises. HTML is famously forgiving. Forget a closing </li>, nest a block element somewhere illegal, or omit <tbody> inside a table, and the browser doesn't throw an error — it quietly fixes your markup as it builds the tree, following a detailed set of rules. The DOM you end up with can therefore be tidier, or subtly different, than the tags you typed. "View source" shows your original HTML; the browser's DevTools "Elements" panel shows the DOM — and when they differ, this is why.
Second, and far more importantly, the DOM changes after load. The instant any JavaScript runs, it can add nodes, delete them, move them, or rewrite their text — and it usually does. On a modern site, what you see is often almost entirely constructed by script after the initial HTML arrived.
JavaScript's doorway to the page
Here's the payoff, and the reason the DOM matters so much to a frontend developer: the DOM is the one and only way JavaScript can touch the page. There is no other channel. Every visual change your code makes — showing a menu, updating a counter, inserting a search result — is an edit to this tree of nodes.
// Find a node in the tree
const title = document.querySelector('h1')
// Change its text — edits the text node
title.textContent = 'Hello, browser'
// Build and attach a new node
const p = document.createElement('p')
p.textContent = 'Added by JavaScript.'
document.body.appendChild(p)Every one of these operations reaches into the DOM tree and modifies it. querySelector walks the tree to find a node; textContent rewrites a text node; appendChild grafts a new branch on. And here's the connection back to the pipeline: the moment you change the DOM, the browser has to update the picture. It re-runs the later rendering stages — style, layout, paint — to reflect your edit on screen. Frameworks like React exist largely to manage these DOM edits efficiently on your behalf, but underneath every one of them, it's still nodes being added, removed, and updated in this tree.
Building the tree, incrementally
One last detail that pays off later: the browser builds the DOM as the HTML streams in, not in one shot at the end. It reads the bytes, tokenises them into tags and text, and grows the tree node by node. This is why a page can start showing its header while its footer is still downloading — the top of the tree exists before the bottom does.
It's also why a <script> sitting in the middle of your HTML is such a big deal: by default, the parser must stop building the tree, download and run that script, and only then continue — because the script might change the very part of the DOM being built. That pause is the "parser-blocking" behaviour from the overview's table, and it's the reason scripts so often live at the end of <body>, or carry defer. We'll see the flip side — how the browser stays responsive despite all this single-threaded work — when we reach the event loop.
Where this leaves us
You now have the browser's core data structure. The DOM is a live tree of nodes, built from your HTML, repaired and normalised on the way in, and continuously edited by JavaScript — and the rendered page is simply a picture of it at a moment in time.
But a tree of elements only tells the browser what is on the page, not how it should look. A heading is just a heading until something says it's 32 pixels, bold, and dark green. That "how it looks" is a second tree, built from your CSS and married to this one. Next: CSS and the render tree, where structure meets style.