Document Object Model

Tool

The live object structure a browser builds out of a web page so that code can find parts of it and change them.

Why it exists

On the early web a page was drawn once and that was it. The browser laid out whatever document the server had sent, and changing any single thing inside it meant requesting the address again and receiving the whole document over. Removing one item from a list flashed the screen white and redrew everything from the top.

Browser vendors then each shipped their own answer, which made it worse. One exposed the elements inside a page under one set of names, another used names that shared nothing with the first. Building the same feature meant detecting which browser the code was running in and then writing two versions of it. Scripts that opened with a browser-detection branch were the normal shape of front-end code at the time.

So the way code reaches into a document was standardized. Once a browser parses a page, it keeps the result as a set of objects with agreed-upon names and behavior, and code addresses those objects the same way no matter which browser is running. The Document Object Model (DOM) is the name for both that specification and the structure it produces. When people say JavaScript changes the screen, changing this structure is what they are describing.

What it solves

It turns a document written as text into something code can handle as objects. The browser reads the HTML from the top, makes an object out of every element, and links those objects into a tree that follows how they nest. The document sits at the root, the body under it, a list under the body, and the individual items under the list.

That structure gives code three things to do.

  1. Find — select elements that match a condition. It can grab a single element carrying a unique identifier, or collect every element marked a certain way.
  2. Change — edit the text or attributes of an element that was found, build a new element and insert it at a chosen position, or detach one that was there. The change shows up on screen immediately.
  3. Listen — attach a function to an element and wait for something to happen to it. Click, keystroke and scroll are all events in this sense.

Deleting one item from the Pagedeck document list shows all three at once. A listener sits on the trash icon, the click sends a delete request to the server, and a successful response detaches only the element for that item. The remaining rows and the scroll position stay where they were. In the era of re-requesting the whole document, the same action repainted the entire screen.

There is one more thing worth knowing. The structure the browser built lives apart from the original document. The file the server sent may list ten items, but once code detaches one, the structure currently on screen holds nine. What a person sees always comes from this structure, never from the file.

Alternatives

Several approaches let you avoid reaching into the structure by hand. None of them change the fact that the structure gets modified at the end — they change who does the modifying.

  1. Split the screen into pieces and let a library handle it — this is what working with components means. Instead of writing down what to change and in what order, you describe what the screen should look like right now, and the library compares that against the previous description and applies only the differences. The class of bug where a developer updates things in the wrong order mostly disappears.
  2. Draw it on the server first — server-side rendering (SSR). The server sends down a finished document for the first screen, so the browser can build the structure and show it as soon as it arrives. The cost is a separate hydration step that attaches behavior to markup that was drawn elsewhere.
  3. Don't touch it at all — things where only the visible state changes, like a menu that folds open or an element that reacts to the pointer, can be handled in CSS. No code runs, so it is faster and there is less to break.

None of the three make the structure go away. A library still creates and detaches elements under the same standard names, and a document sent from the server still gets converted into the same structure once it reaches the browser. That is why questions about why a screen is slow, or why it refuses to update, end up one layer down at this structure.

How it sounds at work

"Let's not touch the DOM directly here — drive it from state instead."

A proposal to stop editing the screen by hand and let the library apply changes when a value changes.

"There are three thousand rows, so we have far too many DOM nodes. Let's only render what's visible."

More elements means more for the browser to compute, so build only the portion currently in view.

"Open the DOM in the console — that attribute isn't there."

Inspecting the structure of the current page in developer tools and finding a value missing that the original document should have supplied.

At Pagedeck, Theo starts here when a report comes in that a screen feels slow. He opens developer tools, counts how many elements currently exist, and checks how many of them get recalculated on a single interaction. On the document list there was a stretch where opening one item redrew the whole list; the cause was neither the server nor the network but code that was touching rows that had not changed.

What people get wrong

Plenty of people take the DOM to be part of JavaScript. Since it is almost always reached through JavaScript, it reads like part of that language. It is actually a separate specification the browser exposes, and JavaScript is one of the languages that can call into it. Missing that distinction makes it hard to explain why the same code does nothing when JavaScript runs on a server: there is no browser and no document there, so there is no structure to operate on.

The claim that touching the DOM is inherently slow is the other common one. The name turns up in every performance conversation, which is enough to fix that idea in place. But changing a single element is cheap; the expense comes from repeatedly reading computed layout right after writing to it. Measure the height of 100 rows and adjust them one at a time, alternating, and the browser recalculates 100 times. Memorizing the rule as "avoid the DOM" leads teams to adopt a whole library for a problem that batching the reads and the writes separately would have solved.

Easily confused with

TermWhat it isHow it differs from the DOM
HTMLText that describes the structure of a documentHTML is the source you hand to the browser; the DOM is the object structure the browser builds by reading it. Editing the source file leaves an open page unchanged, and editing the structure leaves the source file unchanged

Where to go next

  • Frontend

    see where this structure sits in the whole path from code to pixels

  • HTML

    learn the source document this structure is built from

Last updated 2026-09-16