What Is the Document Object Model (DOM)?
The DOM is the browser’s object-based representation of a document. Learn how its nodes and APIs relate to HTML and JavaScript, with runnable examples.
The Document Object Model (DOM) is a programming interface that represents a document as an ordered tree of objects called nodes. A browser builds this representation when it parses HTML, and scripts commonly use JavaScript to find, inspect, and change the document through DOM APIs. The DOM is not the HTML source, a screenshot, or a programming language.
How the DOM represents a document
Consider this HTML:
<html>
<body>
<h1>Hello</h1>
<p>Welcome.</p>
</body>
</html>
A simplified view of its DOM is:
Document
└── html
└── body
├── h1
│ └── "Hello"
└── p
└── "Welcome."
The browser creates objects and relationships from the parsed document. The DOM is therefore a structured representation, not merely the characters in the source file. The actual tree can include whitespace text nodes too, so this compact diagram leaves some nodes out.
DOM tree order is meaningful. Each node can have a parent, children, and siblings; tree traversal follows document order. For example, a script can move from a paragraph to its parent element or select all paragraphs in the document.
Nodes, elements, and attributes
A node is a general kind of object in the document tree. Common node types include the document itself, the document type declaration, elements, text, and comments. An element is one kind of node: it represents markup such as <body> or <p>. Thus every element is a node, but not every node is an element.
| Term | Meaning | Example |
|---|---|---|
| Document | The root object for a document | document in a browser page |
| Element | A node representing a markup element | <p> |
| Text node | Text contained in the document tree | Welcome. |
| Comment node | A comment represented in the tree | <!-- note --> |
| Attribute | Data associated with an element, represented separately from its child nodes | id="intro" |
Attributes such as id and class describe an element, but are not child nodes in the main tree. The distinction matters when traversing: childNodes can include text and comment nodes, while children contains child elements.
DOM, HTML, and JavaScript: how they differ
| Concept | What it is | Typical role |
|---|---|---|
| HTML source | Markup text | Input the browser parses |
| DOM | An object model and set of interfaces for documents | Representation that programs can inspect and manipulate |
| JavaScript | A programming language | Commonly calls browser DOM APIs |
| HTML DOM API | HTML-specific interfaces within the DOM ecosystem | Provides specialized interfaces and behavior for HTML elements |
The DOM is not part of the JavaScript language itself. A browser exposes DOM objects and methods to scripts, and JavaScript is a common language used to call them. The general DOM model is also not limited to HTML; formats such as SVG have specialized interfaces as well. The WHATWG DOM Standard specifies the general model, while the HTML standard defines HTML-specific interfaces.
What developers use the DOM for
DOM APIs let a script find nodes, read their properties, navigate relationships, create or remove nodes, and update content. For example, this browser-side code selects every paragraph and changes the first one:
<p>Welcome.</p>
<p>More information.</p>
<script>
const paragraphs = document.querySelectorAll("p");
if (paragraphs.length > 0) {
paragraphs[0].textContent = "Updated text";
}
</script>
querySelectorAll() returns the matching elements for a CSS selector. textContent reads or replaces text content. This code must run in a browser document; it will not work in a plain Node.js process unless that process provides a DOM implementation.
Other common tools include querySelector() for the first matching element, parentNode and childNodes for general node relationships, and children for element children. Use the API that matches the kind of node you need to find or traverse.
See the DOM in a browser
- Open a page in a browser and open its developer tools.
- In the Elements or Inspector panel, inspect the document structure the browser has parsed.
- In the JavaScript console, try
document.querySelector("h1")to retrieve the first heading element, ordocument.querySelectorAll("p")to retrieve matching paragraphs. - Inspect properties such as
textContent,parentElement, andchildrento see content and relationships.
The Elements panel is a convenient view of the document structure, but it does not mean the DOM tree and the browser’s rendered appearance are the same thing. A screenshot shows pixels; the DOM exposes structured objects and relationships.
Or skip the browser setup
To capture a rendered page as an image, use ScreenshotNeo, a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for parameters.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
- Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers identify the page verdict and billing status.
- An MCP server lets Claude, Cursor, and other MCP clients use
take_screenshot,get_page_info, andcapture_pdf. - The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.
Sign up free for 1,000 screenshots a month, with no card required.
Common DOM misconceptions and troubleshooting
| Symptom or assumption | Cause | Fix |
|---|---|---|
document.querySelector(...) returns null |
No element matched, the selector is wrong, or the code ran before the element was parsed. | Check the selector and confirm the element exists. Run the script after the relevant markup is parsed, such as by placing it after the markup or waiting for the document to be ready. |
| A selector returns fewer elements than expected | The selector only matches elements in the current document and matching state; content may not yet exist or may be in another document or shadow tree. | Check when the content is created and query the appropriate document or shadow root. |
children omits text or comments |
children is element-focused. |
Use childNodes if text and comment nodes are relevant; account for whitespace text nodes. |
| Changing a JavaScript variable does not change the page | Changing a variable is not the same as changing a DOM object. | Set a DOM property or use a DOM method, such as assigning to an element’s textContent. |
document is undefined in Node.js |
Node.js does not provide a browser page’s global DOM by default. | Run the code in a browser, or use a browser automation or DOM implementation library appropriate to the task. |
| The source HTML and inspected DOM differ | Parsing can normalize markup, and scripts can subsequently update the document. | Compare the original response or source with the live DOM in developer tools; they represent different stages and forms. |
Performance, reliability, and cost considerations
The DOM is a conceptual and API model, not a promise about the speed of a particular operation. This overview does not imply a benchmark. For reliable code, check whether a selector found a match, account for when scripts run, and be explicit about whether you need all child nodes or only element children. If a page changes dynamically, the DOM you inspect can change as scripts update it.
Using browser DOM APIs in a page requires a browser document. For a screenshot, a browser-based capture service can handle page loading and rendering without requiring you to install and manage a browser in your own code. ScreenshotNeo offers a free tier of 1,000 shots monthly, followed by paid plans from $5 for 3,000; its billing rules exclude bot checks, blank pages, timeouts, failed loads, and cache hits.
Frequently asked questions
Is the DOM the same for every document type?
The core DOM concepts apply to documents generally, while document formats can define specialized interfaces. HTML and SVG are examples with their own relevant interfaces.
Does changing the DOM change the original HTML file?
A script changes the live document representation in the browser. That does not by itself rewrite the original file or server response.
Is the DOM the same as a screenshot?
No. The DOM represents structured document objects; a screenshot is an image of rendered pixels.
Where is the formal definition maintained?
The WHATWG maintains the DOM Standard. MDN provides an approachable overview and guides to DOM anatomy and traversal.


