What is the DOM in JavaScript? A Beginner Guide
Learn what the DOM is in JavaScript, how browsers build it from HTML, and why it matters for creating dynamic, interactive web pages.
Every time you click a button and a dropdown appears, type in a search box and suggestions show up, or scroll and new content loads, JavaScript is manipulating the DOM. The Document Object Model is the bridge between your HTML document and the JavaScript code that makes it interactive. Without the DOM, JavaScript could not change a single pixel on the page.
This guide explains what the DOM is, how browsers create it, and why it is the foundation of every interactive web application.
What Does DOM Stand For?
DOM stands for Document Object Model. Let's break down each word:
- Document: The HTML page loaded in the browser
- Object: The browser converts every HTML element into a JavaScript object
- Model: These objects are organized in a tree structure that models the document's hierarchy
The DOM is not the HTML source code itself. It is a live, in-memory representation of your document that JavaScript can read and modify. When JavaScript runs in the browser, it interacts with this model, not with the raw HTML text.
// The DOM turns HTML into objects you can work with
const heading = document.querySelector("h1");
console.log(typeof heading); // "object" - it's a JavaScript object
console.log(heading.textContent); // The text inside the h1 elementHow the Browser Creates the DOM
When you load a web page, the browser follows a specific sequence to turn raw HTML into the DOM:
- Download: The browser fetches the HTML file from the server
- Parse: It reads the HTML character by character, converting tags into tokens
- Build the DOM tree: Tokens are organized into a tree of node objects
- Render: The tree is combined with CSS to paint the page on screen
<!-- This HTML source... -->
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
<p>Welcome to the page.</p>
</body>
</html>Gets converted into a tree:
document
└── html
├── head
│ └── title
│ └── "My Page" (text node)
└── body
├── h1
│ └── "Hello" (text node)
└── p
└── "Welcome to the page." (text node)
Every piece of the HTML becomes a node in this tree. Elements, text, comments, and even whitespace all become nodes.
The DOM Is Not Your HTML
This is a critical distinction. The DOM and the HTML source code are related but not identical:
| Aspect | HTML Source | DOM |
|---|---|---|
| What it is | Text file on the server | Live objects in browser memory |
| Can JavaScript modify it? | No | Yes |
| Updates when changed | No (static file) | Yes (re-renders immediately) |
| Includes browser corrections | No | Yes (fixes errors) |
| Contains JS-generated content | No | Yes |
The browser fixes malformed HTML when building the DOM:
<!-- Your HTML (missing closing tags, no tbody) -->
<table>
<tr><td>Data</td></tr>
</table>
<!-- The DOM automatically adds a <tbody> -->
<!-- document.querySelector("tbody") returns an element, even though
tbody was never in your HTML source -->JavaScript-generated content also exists only in the DOM, not in the source:
// This paragraph exists in the DOM but not in the HTML file
const newParagraph = document.createElement("p");
newParagraph.textContent = "Added by JavaScript";
document.body.appendChild(newParagraph);Types of DOM Nodes
Not everything in the DOM is an HTML element. The DOM contains several node types:
const body = document.body;
// Element nodes represent HTML tags
console.log(body.nodeType); // 1 (ELEMENT_NODE)
// Text nodes represent text content
const textNode = document.querySelector("h1").firstChild;
console.log(textNode.nodeType); // 3 (TEXT_NODE)
// Comment nodes represent HTML comments
// <!-- This becomes a comment node -->
// commentNode.nodeType === 8 (COMMENT_NODE)
// The document itself is a node
console.log(document.nodeType); // 9 (DOCUMENT_NODE)| Node Type | nodeType Value | Example |
|---|---|---|
| Element | 1 | <div>, <p>, <a> |
| Text | 3 | Text between tags |
| Comment | 8 | <!-- comment --> |
| Document | 9 | The document object |
| DocumentFragment | 11 | Container for batch operations |
The document Object
JavaScript accesses the DOM through the global document object. This object is your entry point for everything DOM-related:
// Access the entire document
console.log(document.title); // Page title
console.log(document.URL); // Current URL
console.log(document.characterSet); // "UTF-8"
// Access key elements
console.log(document.head); // <head> element
console.log(document.body); // <body> element
console.log(document.documentElement); // <html> element
// Find elements
const main = document.getElementById("main");
const buttons = document.querySelectorAll("button");
const firstLink = document.querySelector("a");The document object provides methods to find elements, create new elements, and modify the page. It is the single most important object in browser-based JavaScript.
What You Can Do with the DOM
The DOM lets JavaScript do four fundamental operations:
1. Read Content
// Read text
const heading = document.querySelector("h1");
console.log(heading.textContent); // "Hello World"
// Read attributes
const link = document.querySelector("a");
console.log(link.href); // Full URL
console.log(link.getAttribute("href")); // Attribute value as-is
// Read styles
const box = document.querySelector(".box");
console.log(getComputedStyle(box).backgroundColor);2. Change Content
// Change text
heading.textContent = "New Title";
// Change HTML content
const container = document.querySelector(".container");
container.innerHTML = "<strong>Bold text</strong>";
// Change attributes
link.setAttribute("href", "https://runehub.dev");
link.classList.add("active");3. Create and Add Elements
// Create a new element
const card = document.createElement("div");
card.className = "card";
card.innerHTML = `
<h2>New Card</h2>
<p>Created with JavaScript</p>
`;
// Add it to the page
document.body.appendChild(card);4. Remove Elements
// Remove an element
const oldElement = document.querySelector(".outdated");
oldElement.remove();
// Or using parent reference
const parent = document.querySelector(".container");
const child = parent.querySelector(".item");
parent.removeChild(child);The DOM Is Live
Changes to the DOM are reflected immediately on the page. There is no "save" or "commit" step:
// This changes the page instantly
document.body.style.backgroundColor = "lightblue";
// This adds visible content immediately
const alert = document.createElement("div");
alert.textContent = "Something happened!";
alert.style.padding = "20px";
alert.style.backgroundColor = "yellow";
document.body.prepend(alert);This live nature is what makes the DOM powerful (instant updates) and dangerous (any bug in your DOM code is immediately visible to the user).
DOM and Performance
Every DOM operation triggers the browser to potentially recalculate styles, reflow the layout, and repaint the screen. This makes DOM manipulation the most expensive operation in browser JavaScript:
// BAD: triggers 1000 separate reflows
const list = document.querySelector("ul");
for (let i = 0; i < 1000; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i}`;
list.appendChild(li); // Reflow on every iteration
}
// BETTER: batch with DocumentFragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i}`;
fragment.appendChild(li); // No reflow yet
}
list.appendChild(fragment); // Single reflowThis is one reason why frameworks like React use a virtual DOM: they batch changes and apply them to the real DOM in a single operation.
Common Mistakes to Avoid
Accessing DOM Before It Is Ready
// This might fail if the script runs before the HTML is parsed
const button = document.querySelector("#submit"); // null if not yet in DOM
// Fix 1: Place script at the end of body
// Fix 2: Use DOMContentLoaded event
document.addEventListener("DOMContentLoaded", () => {
const button = document.querySelector("#submit"); // Now it exists
});
// Fix 3: Use defer attribute on script tag
// <script src="app.js" defer></script>Confusing innerHTML with textContent
const div = document.querySelector("div");
// textContent sets plain text (safe from injection)
div.textContent = "<b>Bold</b>"; // Displays as literal "<b>Bold</b>"
// innerHTML parses HTML (potential XSS risk with user input)
div.innerHTML = "<b>Bold</b>"; // Displays as BoldStoring DOM References to Removed Elements
const element = document.querySelector(".dynamic");
element.remove();
// The variable still holds the object, but it's disconnected from the page
console.log(element.textContent); // Still accessible in memory
document.body.appendChild(element); // Can re-add itBest Practices
- Wait for the DOM to load before running scripts. Use
DOMContentLoaded,defer, or place scripts at the end of the body. - Cache DOM references in variables. Calling
document.querySelector()repeatedly for the same element wastes cycles. - Batch DOM changes using
DocumentFragmentor by building HTML strings before inserting them. - Use
textContentfor plain text andinnerHTMLonly when you need to parse HTML. Never useinnerHTMLwith user input. - Understand that the DOM is live. Changes are instant, so validate your modifications before applying them.
Rune AI
Key Insights
- The DOM is a live tree of objects: browsers convert HTML into a tree structure where each element, text node, and comment is a JavaScript object
- The
documentobject is your entry point: all DOM operations start withdocument.querySelector(),document.createElement(), and related methods - The DOM is not your HTML: browsers correct errors, JavaScript adds content, and the DOM can diverge significantly from the source HTML
- DOM changes are instant and expensive: every modification can trigger layout recalculation, so batch operations and cache references for performance
- Scripts must wait for the DOM: use
defer,DOMContentLoaded, or bottom-of-body script placement to ensure elements exist before your code runs
Frequently Asked Questions
Is the DOM part of JavaScript?
What is the difference between the DOM and the virtual DOM?
Can CSS interact with the DOM?
What happens to the DOM when JavaScript adds elements?
Do all browsers create the same DOM from the same HTML?
Conclusion
The DOM is the live, in-memory tree of objects that browsers create from your HTML. It is not the HTML source code, but a structured representation that JavaScript can read, modify, create, and delete in real time. Every interactive feature on every website works through DOM manipulation. Understanding the DOM is the gateway to building dynamic web applications with JavaScript.
More in this topic
OffscreenCanvas API in JS for UI Performance
Master the OffscreenCanvas API to offload rendering from the main thread. Covers worker-based 2D and WebGL rendering, animation loops inside workers, bitmap transfer, double buffering, chart rendering pipelines, image processing, and performance measurement strategies.
Advanced Web Workers for High Performance JS
Master Web Workers for truly parallel JavaScript execution. Covers dedicated and shared workers, structured cloning, transferable objects, SharedArrayBuffer with Atomics, worker pools, task scheduling, Comlink RPC patterns, module workers, and performance profiling strategies.
JavaScript Macros and Abstract Code Generation
Master JavaScript code generation techniques for compile-time and runtime metaprogramming. Covers AST manipulation, Babel plugin authorship, tagged template literals as macros, code generation pipelines, source-to-source transformation, compile-time evaluation, and safe eval alternatives.