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.

JavaScriptbeginner
10 min read

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.

javascriptjavascript
// 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 element

How the Browser Creates the DOM

When you load a web page, the browser follows a specific sequence to turn raw HTML into the DOM:

  1. Download: The browser fetches the HTML file from the server
  2. Parse: It reads the HTML character by character, converting tags into tokens
  3. Build the DOM tree: Tokens are organized into a tree of node objects
  4. Render: The tree is combined with CSS to paint the page on screen
htmlhtml
<!-- 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:

CodeCode
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:

AspectHTML SourceDOM
What it isText file on the serverLive objects in browser memory
Can JavaScript modify it?NoYes
Updates when changedNo (static file)Yes (re-renders immediately)
Includes browser correctionsNoYes (fixes errors)
Contains JS-generated contentNoYes

The browser fixes malformed HTML when building the DOM:

htmlhtml
<!-- 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:

javascriptjavascript
// 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:

javascriptjavascript
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 TypenodeType ValueExample
Element1<div>, <p>, <a>
Text3Text between tags
Comment8<!-- comment -->
Document9The document object
DocumentFragment11Container 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:

javascriptjavascript
// 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

javascriptjavascript
// 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

javascriptjavascript
// 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

javascriptjavascript
// 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

javascriptjavascript
// 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:

javascriptjavascript
// 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:

javascriptjavascript
// 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 reflow

This 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

javascriptjavascript
// 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

javascriptjavascript
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 Bold

Storing DOM References to Removed Elements

javascriptjavascript
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 it

Best Practices

  1. Wait for the DOM to load before running scripts. Use DOMContentLoaded, defer, or place scripts at the end of the body.
  2. Cache DOM references in variables. Calling document.querySelector() repeatedly for the same element wastes cycles.
  3. Batch DOM changes using DocumentFragment or by building HTML strings before inserting them.
  4. Use textContent for plain text and innerHTML only when you need to parse HTML. Never use innerHTML with user input.
  5. Understand that the DOM is live. Changes are instant, so validate your modifications before applying them.
Rune AI

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 document object is your entry point: all DOM operations start with document.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
RunePowered by Rune AI

Frequently Asked Questions

Is the DOM part of JavaScript?

No. The DOM is a browser API, not part of the JavaScript language itself. JavaScript running in [Node.js](/tutorials/programming-languages/javascript/how-to-run-javascript-in-the-browser-and-node) does not have a DOM because there is no browser document. The DOM is defined by the W3C and WHATWG standards, and browsers implement it as a set of objects and methods that JavaScript can use.

What is the difference between the DOM and the virtual DOM?

The DOM is the real, browser-managed tree of HTML elements. The virtual DOM is a lightweight JavaScript copy of that tree used by frameworks like React. Changes are first applied to the virtual DOM, which is fast because it does not trigger rendering. The framework then computes the minimum set of real DOM changes needed and applies them in a batch.

Can CSS interact with the DOM?

CSS styles elements based on their position in the DOM tree, their attributes, and their classes. CSS selectors like `.active`, `#header`, and `:first-child` all reference the DOM structure. JavaScript can dynamically change classes, attributes, and the DOM structure to trigger different CSS rules, creating visual interactivity.

What happens to the DOM when JavaScript adds elements?

When JavaScript adds elements (via `appendChild`, `insertBefore`, or setting `innerHTML`), the DOM tree is updated immediately. The browser then triggers a style recalculation, layout reflow, and repaint for the affected area. The HTML source file on the server remains unchanged, so refreshing the page resets to the original HTML.

Do all browsers create the same DOM from the same HTML?

For valid HTML, yes. All modern browsers follow the same HTML5 parsing specification (defined by WHATWG) to build the DOM. Minor differences can occur with malformed HTML where the error-correction rules have edge cases. Using valid, well-structured HTML ensures consistent DOM creation across browsers.

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.