Browser Environment, DOM and BOM in JavaScript
JavaScript was born in the browser, and the browser remains its most important runtime environment. But the browser gives JavaScript far more than just a place to execute code. It provides an entire ecosystem of objects, APIs, and interfaces that let your scripts interact with the web page, the browser window, the user's navigation history, and even the device itself.
When you write document.querySelector() or window.location.href, you are not using core JavaScript language features. You are using objects provided by the browser environment. Understanding how this environment is structured, what each major component does, and how the different specifications define them is essential for writing effective browser-side JavaScript.
This guide maps out the complete browser environment, from the global window object through the DOM and BOM, showing you what each part provides and where the boundaries between them lie.
The Browser as a JavaScript Host Environmentβ
JavaScript the language (defined by the ECMAScript specification) knows nothing about web pages, HTML elements, HTTP requests, or browser tabs. It defines variables, functions, objects, promises, and other programming constructs. But JavaScript was designed to run inside a host environment that provides additional objects and APIs specific to the platform.
The browser is the most well-known host environment, but it is not the only one:
| Host Environment | What It Provides |
|---|---|
| Browser | DOM, BOM, Fetch API, Canvas, Web Workers, local storage, etc. |
| Node.js | File system, HTTP server, child processes, streams, buffers, etc. |
| Deno | Secure file/network access, built-in TypeScript, Web-compatible APIs |
| Bun | Fast runtime, built-in bundler, Node.js compatible APIs |
Each host environment takes the same JavaScript language and wraps it with platform-specific objects. When you write document.getElementById("app") in a browser, document is not part of JavaScript itself. It is an object provided by the browser's host environment.
What the Browser Providesβ
When a browser loads a web page containing JavaScript, it creates a complete execution environment that includes:
- The JavaScript engine (V8 in Chrome/Edge, SpiderMonkey in Firefox, JavaScriptCore in Safari) that parses and executes your code
- The global object (
window) that serves as both the JavaScript global scope and the entry point to browser APIs - The DOM (Document Object Model) for interacting with the page's HTML structure
- The BOM (Browser Object Model) for interacting with the browser itself
- Web APIs like
fetch,setTimeout,localStorage, and hundreds of others
The High-Level Architectureβ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β window β
β (Global Object) β
β β
β ββββββββββββββββ βββββββββββββββββββββββββ β
β β DOM β β BOM β β
β β β β β β
β β document β β navigator β β
β β βββ html β β location β β
β β β βββ headβ β history β β
β β β βββ bodyβ β screen β β
β β β βββ β β fetch() β β
β β β ... β β setTimeout() β β
β β βββββββββββ β β localStorage β β
β ββββββββββββββββ β XMLHttpRequest β β
β β alert / confirm β β
β βββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β JavaScript Core (ECMAScript) β β
β β Object, Array, Promise, Map, Set ... β β
β βββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Everything sits under the window object. The core JavaScript language provides data structures and logic. The DOM provides page manipulation. The BOM provides browser interaction. Together, they form the complete browser environment.
The window Object: Global Object and Browser Interfaceβ
The window object is the most important object in browser-side JavaScript. It plays three distinct roles simultaneously, which is unusual and sometimes confusing.
Role 1: The JavaScript Global Objectβ
In browsers, window is the global object defined by the ECMAScript specification. All global variables and functions become properties of window:
var greeting = "Hello";
console.log(window.greeting); // "Hello"
function sayHi() {
return "Hi!";
}
console.log(window.sayHi()); // "Hi!"
Built-in JavaScript objects are also properties of window:
console.log(window.Array === Array); // true
console.log(window.Promise === Promise); // true
console.log(window.Object === Object); // true
console.log(window.JSON === JSON); // true
let and const declarations at the top level do not become properties of window. Only var declarations and function declarations do:
var oldStyle = "I'm on window";
let modern = "I'm NOT on window";
const alsoModern = "Neither am I";
console.log(window.oldStyle); // "I'm on window"
console.log(window.modern); // undefined
console.log(window.alsoModern); // undefined
This is one of several reasons to prefer let and const over var.
Role 2: The Browser Window Interfaceβ
window represents the browser window (or tab) and provides properties and methods for controlling it:
// Window dimensions (viewport)
console.log(window.innerWidth); // 1920 (viewport width in pixels)
console.log(window.innerHeight); // 1080 (viewport height in pixels)
// Outer dimensions (entire browser window including chrome)
console.log(window.outerWidth); // 1920
console.log(window.outerHeight); // 1120
// Window position on screen
console.log(window.screenX); // 0
console.log(window.screenY); // 0
// Scroll position
console.log(window.scrollX); // 0 (horizontal scroll)
console.log(window.scrollY); // 250 (vertical scroll)
// Scrolling
window.scrollTo(0, 0); // Scroll to top
window.scrollBy(0, 100); // Scroll down 100px
window.scrollTo({ top: 0, behavior: "smooth" }); // Smooth scroll to top
Role 3: The Container for DOM and BOMβ
window holds references to all the browser APIs:
// DOM entry point
console.log(window.document); // The Document object
// BOM objects
console.log(window.navigator); // Browser/device info
console.log(window.location); // Current URL
console.log(window.history); // Navigation history
console.log(window.screen); // Screen info
// Web APIs
console.log(typeof window.fetch); // "function"
console.log(typeof window.setTimeout); // "function"
console.log(typeof window.localStorage); // "object"
console.log(typeof window.console); // "object"
Implicit window Referenceβ
Because window is the global object, you almost never need to write window. explicitly. These pairs are identical:
// These are the same:
document.getElementById("app");
window.document.getElementById("app");
// These are the same:
setTimeout(() => console.log("hi"), 1000);
window.setTimeout(() => console.log("hi"), 1000);
// These are the same:
alert("Hello!");
window.alert("Hello!");
// These are the same:
console.log("test");
window.console.log("test");
There are a few cases where writing window. explicitly is necessary or useful:
// 1. Distinguishing a global from a local variable
const location = "New York"; // Local variable shadows window.location
console.log(location); // "New York"
console.log(window.location); // Location object (the URL)
// 2. Checking if a global variable exists without ReferenceError
if (window.jQuery) {
// jQuery is loaded
}
// Without 'window.', this throws if jQuery doesn't exist:
// if (jQuery) { ... } // ReferenceError if not defined
// 3. Setting a truly global variable from inside a module
window.myGlobalConfig = { debug: true };
globalThis: The Universal Global Objectβ
globalThis was introduced in ES2020 to provide a single way to access the global object across all environments:
// In browsers: globalThis === window
console.log(globalThis === window); // true
// In Node.js: globalThis === global
// In Web Workers: globalThis === self
// Works everywhere:
console.log(globalThis.setTimeout); // function
Use globalThis when writing code that needs to work in multiple environments (browser, Node.js, workers).
DOM (Document Object Model): The Page as a Treeβ
The DOM is a programming interface for web pages. It represents the HTML document as a tree of objects, where each HTML element, text node, and comment becomes a node in the tree. JavaScript interacts with the page entirely through this tree.
HTML to DOM Transformationβ
When the browser loads an HTML document, it parses the HTML and constructs the DOM tree:
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
<p>Welcome to <em>my</em> page</p>
</body>
</html>
This becomes a tree:
document
βββ html
βββ head
β βββ title
β βββ "My Page" (text)
βββ body
βββ h1
β βββ "Hello" (text)
βββ p
βββ "Welcome to " (text)
βββ em
β βββ "my" (text)
βββ " page" (text)
The document Objectβ
The document object is the entry point to the DOM. It represents the entire HTML document and provides methods for finding, creating, and modifying elements:
// Finding elements
const heading = document.getElementById("main-title");
const buttons = document.querySelectorAll(".btn");
const firstLink = document.querySelector("a");
// Creating elements
const newDiv = document.createElement("div");
newDiv.textContent = "I was created by JavaScript";
newDiv.className = "dynamic-content";
// Adding to the page
document.body.appendChild(newDiv);
// Modifying content
heading.textContent = "Updated Title";
heading.style.color = "blue";
// Accessing page information
console.log(document.title); // "My Page"
console.log(document.URL); // "https://example.com/page"
console.log(document.contentType); // "text/html"
The DOM Is Liveβ
The DOM is not a static snapshot. It reflects the current state of the page, and modifications to the DOM are immediately reflected on screen:
// Every change is instant and visible
document.body.style.backgroundColor = "lightblue"; // Page turns blue immediately
const p = document.createElement("p");
p.textContent = "This text appears instantly";
document.body.appendChild(p); // Visible on screen now
// DOM queries return live results (for some methods)
const divs = document.getElementsByTagName("div"); // Live HTMLCollection
document.body.appendChild(document.createElement("div"));
console.log(divs.length); // Increased by 1: the collection updated automatically
What the DOM Standard Definesβ
The DOM is defined by its own specification maintained by the WHATWG. It defines:
- The node types (
Element,Text,Comment,Document, etc.) - The tree structure and navigation (
parentNode,childNodes,nextSibling) - Element manipulation (
createElement,appendChild,remove) - Event handling (
addEventListener,dispatchEvent) - Selectors (
querySelector,querySelectorAll)
The DOM specification is separate from both the ECMAScript specification (which defines JavaScript the language) and the HTML specification (which defines what elements exist and how they behave). However, they work closely together.
BOM (Browser Object Model): navigator, location, history, screenβ
The BOM encompasses everything the browser provides to JavaScript outside the document itself. While the DOM deals with the page content, the BOM deals with the browser window, navigation, user agent, and other browser-level features.
Unlike the DOM, the BOM was historically not standardized. Each browser implemented its own version. Most BOM features are now part of the HTML specification, but the term "BOM" is still widely used.
navigator: Browser and Device Informationβ
The navigator object provides information about the browser and the device:
// Browser identification
console.log(navigator.userAgent);
// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
// Language
console.log(navigator.language); // "en-US"
console.log(navigator.languages); // ["en-US", "en", "fr"]
// Online status
console.log(navigator.onLine); // true or false
// Hardware
console.log(navigator.hardwareConcurrency); // 8 (CPU cores)
console.log(navigator.maxTouchPoints); // 0 (desktop) or 5+ (touch device)
console.log(navigator.deviceMemory); // 8 (GB, approximate)
// Platform (deprecated but still used)
console.log(navigator.platform); // "Win32", "MacIntel", "Linux x86_64"
navigator also hosts several important APIs:
// Clipboard
await navigator.clipboard.writeText("Copied text!");
const text = await navigator.clipboard.readText();
// Geolocation
navigator.geolocation.getCurrentPosition(
position => {
console.log("Lat:", position.coords.latitude);
console.log("Lng:", position.coords.longitude);
},
error => console.error(error.message)
);
// Media devices (camera, microphone)
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
// Service workers
const registration = await navigator.serviceWorker.register("/sw.js");
// Permissions
const result = await navigator.permissions.query({ name: "notifications" });
console.log(result.state); // "granted", "denied", or "prompt"
// Share API (mobile)
if (navigator.share) {
await navigator.share({
title: "My Article",
text: "Check this out!",
url: "https://example.com/article"
});
}
// Send data when page unloads (analytics)
navigator.sendBeacon("/api/analytics", JSON.stringify({ event: "page_leave" }));
The navigator.userAgent string is notoriously unreliable for browser detection. Every browser includes other browsers' names in its user agent string for historical compatibility reasons. Prefer feature detection (if ("serviceWorker" in navigator)) over user agent sniffing.
location: Current URLβ
The location object represents the current URL and provides methods to navigate:
// Given URL: https://example.com:8080/path/page.html?id=42&lang=en#section2
console.log(location.href); // "https://example.com:8080/path/page.html?id=42&lang=en#section2"
console.log(location.protocol); // "https:"
console.log(location.host); // "example.com:8080"
console.log(location.hostname); // "example.com"
console.log(location.port); // "8080"
console.log(location.pathname); // "/path/page.html"
console.log(location.search); // "?id=42&lang=en"
console.log(location.hash); // "#section2"
console.log(location.origin); // "https://example.com:8080"
Navigating:
// Navigate to a new page (adds to history)
location.href = "https://example.com/new-page";
// or
location.assign("https://example.com/new-page");
// Navigate and replace current history entry (no back button)
location.replace("https://example.com/new-page");
// Reload the current page
location.reload();
// Change only part of the URL
location.hash = "#new-section"; // Scrolls to #new-section, no page reload
location.search = "?page=2"; // Reloads with new query string
Working with query parameters:
// Parse query parameters with URLSearchParams
const params = new URLSearchParams(location.search);
console.log(params.get("id")); // "42"
console.log(params.get("lang")); // "en"
console.log(params.has("debug")); // false
// Iterate all parameters
for (const [key, value] of params) {
console.log(`${key} = ${value}`);
}
// id = 42
// lang = en
// Modify and apply
params.set("page", "2");
params.delete("lang");
location.search = params.toString(); // Navigates to "?id=42&page=2"
history: Navigation Historyβ
The history object provides access to the browser's session history (the list of pages visited in the current tab):
// Navigate through history
history.back(); // Same as clicking the Back button
history.forward(); // Same as clicking the Forward button
history.go(-2); // Go back 2 pages
history.go(1); // Go forward 1 page
// Number of entries in the history stack
console.log(history.length); // e.g., 5
The History API (for single-page applications):
// Add a new entry to the history without navigating
history.pushState(
{ page: "about" }, // State object (serializable data)
"", // Title (mostly ignored by browsers)
"/about" // URL to display
);
// Replace the current entry without adding a new one
history.replaceState(
{ page: "about", section: "team" },
"",
"/about#team"
);
// Access the current state
console.log(history.state); // { page: "about", section: "team" }
// Listen for back/forward navigation
window.addEventListener("popstate", event => {
console.log("Navigation occurred");
console.log("State:", event.state);
// Update the page content based on the new state
if (event.state) {
renderPage(event.state.page);
}
});
The History API is the foundation of client-side routing in single-page applications (React Router, Vue Router, etc.). It lets you change the URL and manage navigation state without triggering full page reloads.
screen: Display Informationβ
The screen object provides information about the user's display:
// Screen dimensions (full monitor resolution)
console.log(screen.width); // 1920
console.log(screen.height); // 1080
// Available space (minus OS taskbar, dock, etc.)
console.log(screen.availWidth); // 1920
console.log(screen.availHeight); // 1040
// Color depth
console.log(screen.colorDepth); // 24 (bits)
console.log(screen.pixelDepth); // 24
// Device pixel ratio (for high-DPI / Retina displays)
console.log(window.devicePixelRatio); // 1 (standard) or 2 (Retina)
// Screen orientation
console.log(screen.orientation.type); // "landscape-primary"
console.log(screen.orientation.angle); // 0
screen.orientation.addEventListener("change", () => {
console.log("Orientation changed to:", screen.orientation.type);
});
Common use case: responsive behavior in JavaScript:
// Detect if the window is smaller than a breakpoint
if (window.innerWidth < 768) {
loadMobileLayout();
} else {
loadDesktopLayout();
}
// React to window resize
window.addEventListener("resize", () => {
console.log(`Window: ${window.innerWidth} x ${window.innerHeight}`);
});
// Better: use matchMedia for responsive checks
const mobileQuery = window.matchMedia("(max-width: 768px)");
mobileQuery.addEventListener("change", event => {
if (event.matches) {
console.log("Switched to mobile layout");
} else {
console.log("Switched to desktop layout");
}
});
Other BOM Featuresβ
The BOM also includes several standalone functions and objects:
// Dialog boxes
alert("Message to the user");
const confirmed = confirm("Are you sure?"); // true or false
const input = prompt("Enter your name:", "Alice"); // string or null
// Timers
const timeoutId = setTimeout(() => console.log("delayed"), 1000);
clearTimeout(timeoutId);
const intervalId = setInterval(() => console.log("repeating"), 500);
clearInterval(intervalId);
// Storage
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme");
sessionStorage.setItem("tempData", "value");
// Console
console.log("Info message");
console.warn("Warning message");
console.error("Error message");
console.table([{ name: "Alice" }, { name: "Bob" }]);
console.time("operation");
console.timeEnd("operation");
// Encoding
const encoded = btoa("Hello World"); // Base64 encode: "SGVsbG8gV29ybGQ="
const decoded = atob(encoded); // Base64 decode: "Hello World"
const uriSafe = encodeURIComponent("hello world & more");
// "hello%20world%20%26%20more"
The DOM Standard and the HTML Specificationβ
The browser environment is defined by multiple specifications maintained by different organizations. Understanding which specification covers what helps you find the right documentation and understand why certain APIs work the way they do.
The Key Specificationsβ
| Specification | Maintained By | What It Defines |
|---|---|---|
| ECMAScript | TC39 (Ecma International) | The JavaScript language itself: syntax, types, built-in objects, modules |
| DOM | WHATWG | The tree structure, node types, event system, selectors, mutation observers |
| HTML | WHATWG | HTML elements, browser APIs (BOM), window, navigator, location, history, canvas, fetch, storage, workers, etc. |
| CSS Object Model | W3C | CSS manipulation through JavaScript, getComputedStyle, style sheets |
| Fetch | WHATWG | The fetch() API, Request, Response, Headers |
| URL | WHATWG | URL and URLSearchParams objects |
How They Fit Togetherβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ECMAScript (TC39) β
β JavaScript language: let, const, Promise, β
β class, async/await, Array, Object, Map... β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β β
βββββββββββ΄ββββββββββββ ββββββββββββ΄βββββββββββββββ
β DOM (WHATWG) β β HTML (WHATWG) β
β β β β
β Document, Element, β β window, navigator, β
β Node, EventTarget, β β location, history, β
β querySelector, β β HTMLElement types, β
β MutationObserver, β β Canvas, Fetch, β
β Event, CustomEvent β β Web Workers, Storage, β
β β β setTimeout, alert β
βββββββββββββββββββββββ βββββββββββββββββββββββββββ
Why the Separation Mattersβ
The DOM specification is intentionally language-independent. It defines the tree structure and API in abstract terms that could be implemented in any programming language. Java, Python, and other languages have their own DOM implementations for working with XML and HTML documents.
The HTML specification is browser-specific. It defines how HTML elements behave, what attributes they support, and what browser APIs exist. It assumes the DOM as its underlying model but adds all the browser-specific functionality on top.
This separation explains some quirks:
// document.getElementById is defined in the DOM spec
// It works the same way in any DOM implementation
// document.body is defined in the HTML spec
// It's specific to HTML documents and wouldn't exist in an XML DOM
// window.localStorage is defined in the HTML spec
// It's a browser-specific feature with no equivalent in the DOM spec
// Element.querySelector is defined in the Selectors API spec
// But it's referenced from the DOM spec
Finding Documentationβ
When you want to look up how an API works, knowing which specification it belongs to helps you find the authoritative source:
- Language features (syntax, built-in objects): ECMAScript specification or MDN JavaScript Reference
- DOM APIs (document, element, event): DOM Living Standard or MDN DOM Reference
- Browser APIs (window, navigator, fetch, storage): HTML Living Standard or MDN Web APIs
In practice, MDN Web Docs is the most developer-friendly resource. It consolidates information from all specifications and includes browser compatibility tables, examples, and clear explanations.
Living Standards vs. Versioned Specsβ
Both the DOM and HTML specifications are maintained as living standards by WHATWG. This means they are continuously updated rather than released in numbered versions. There is no "DOM 4" or "HTML 6." The spec is always the latest version.
This is different from ECMAScript, which releases numbered editions annually (ES2023, ES2024). However, even ECMAScript's development process is continuous, with proposals moving through stages and landing in the next annual snapshot.
// You might see references to these older, versioned DOM levels:
// DOM Level 1 (1998): basic document/element manipulation
// DOM Level 2 (2000): events, CSS access, traversal
// DOM Level 3 (2004): keyboard events, XPath, validation
// These are historical. The current DOM is a single living standard
// that incorporates and extends all previous levels.
Summaryβ
The browser environment wraps the JavaScript language in a rich ecosystem of objects and APIs. Everything is accessible through the window object, which serves as the global scope, the browser window interface, and the container for all browser APIs.
| Component | Entry Point | What It Provides |
|---|---|---|
| JavaScript Core | Built-in objects (Array, Promise, etc.) | Language features, data structures, logic |
| DOM | document | Page content as a tree, element creation/modification, events |
| BOM | window.* (navigator, location, etc.) | Browser interaction, navigation, device info, storage |
| Web APIs | Various (fetch, localStorage, etc.) | Network requests, storage, multimedia, workers |
| BOM Object | Purpose | Key Properties/Methods |
|---|---|---|
window | Global object, browser window | innerWidth, innerHeight, scrollTo(), open() |
navigator | Browser and device info | userAgent, language, onLine, geolocation, clipboard |
location | Current URL | href, pathname, search, hash, assign(), replace() |
history | Session navigation history | back(), forward(), pushState(), replaceState() |
screen | Display information | width, height, availWidth, colorDepth, orientation |
Key takeaways:
windowis the global object in browsers. Globalvardeclarations and function declarations become its properties, butletandconstdo not.- The DOM turns HTML into a tree of objects you can manipulate with JavaScript. Changes are reflected on screen immediately.
- The BOM provides access to everything outside the document: the URL, navigation history, browser details, and device capabilities.
- Use
globalThisinstead ofwindowwhen writing code that needs to work in multiple environments. - The browser environment is defined by multiple specifications (ECMAScript, DOM, HTML), each covering a different aspect. MDN Web Docs is the best single resource for practical documentation.
- Prefer feature detection (
if ("geolocation" in navigator)) over user agent sniffing for determining browser capabilities.