The Browser as a Runtime
A modern browser is not a viewer — it's a sophisticated application platform with a network stack, multiple parsers, a JIT compiler, and 100+ Web APIs.
The Browser as a Runtime
In one line: Your browser is not a document viewer. It's a 50-million-line application runtime that happens to also display web pages.
The browser does an astonishing amount when you open a tab. It speaks every major network protocol, parses HTML/CSS in milliseconds, JIT-compiles JavaScript to machine code on the fly, drives the GPU to paint pixels, sandboxes pages from each other, talks to your camera and microphone, plays video, stores databases locally, and exposes 200+ APIs to the code running inside it. "Open a browser tab" is closer to "boot a small operating system" than to "open a PDF."
What's inside a browser
A modern browser bundles together:
- A network stack — DNS, TCP/UDP, TLS, HTTP/1.1, HTTP/2, HTTP/3.
- An HTML parser — turns HTML text into the DOM (Document Object Model — a tree of objects in memory).
- A CSS engine — parses stylesheets, calculates which rules apply where.
- A JavaScript engine — V8 (Chrome/Edge), JavaScriptCore (Safari), SpiderMonkey (Firefox). These engines JIT-compile JavaScript to machine code at runtime.
- A layout engine — calculates where every element goes on screen.
- A rendering engine — turns the layout into pixels (often using the GPU).
- Web APIs — hundreds of them (see below).
- A storage layer — cookies, localStorage, IndexedDB, Cache API.
- A security sandbox — isolates pages from each other and from your OS.
The HTML you write looks like text. But the moment the browser parses it, that text becomes a tree of in-memory objects — the DOM. Every <div> is an object with properties (textContent, style, children), methods (addEventListener, appendChild), and references to its parent and siblings.
Once you internalize that, manipulating the page in JavaScript stops feeling magical: you're just calling methods on a tree of objects.
Key Web APIs to know exist
Modern browsers expose remarkable capabilities. You don't need to memorize this list — just know they exist so you know where to look:
| Category | API | What it lets you do |
|---|---|---|
| Network | Fetch API | Make HTTP requests (the modern replacement for XHR) |
| WebSockets | Persistent bidirectional connections | |
| Server-Sent Events | Server-pushed updates over a long-lived HTTP connection | |
| WebRTC | Peer-to-peer video, audio, data (Zoom, Discord voice) | |
| WebTransport | Low-latency multiplexed connections over HTTP/3 | |
| Graphics & media | WebGL / WebGPU | 3D graphics; WebGPU also enables compute shaders |
| Web Audio API | Synthesize and process audio | |
| WebCodecs | Low-level encode/decode of video and audio | |
| Storage | localStorage | Tiny key-value storage (~5MB), sync |
| IndexedDB | Browser-side database for large structured data | |
| Cache API | Programmatic cache, used by Service Workers | |
| Devices | Web Speech API | Text-to-speech and speech recognition |
| WebAuthn | Passwordless auth using passkeys/biometrics | |
| Web NFC / Bluetooth / Serial | Hardware access | |
| File System Access | Read/write local files (with permission) | |
| Performance | Service Workers | Programmable proxy between page and network (offline, push, sync) |
| Web Workers | Run JS on background threads | |
| WebAssembly (Wasm) | Run Rust/C++/Go in the browser at near-native speed | |
| UI | Web Components | Native custom HTML elements |
In 2026, the browser is genuinely a full application platform. The phrase "you can build it on the web" is true for the vast majority of applications.
Open DevTools and run this in the Console of any tab:
Object.keys(window).length
You'll see hundreds — that's the number of global objects and APIs the browser exposes to every page. Then try:
Object.keys(window).filter(k => k.match(/^[A-Z]/)).slice(0, 30)
You'll see names like URL, WebSocket, Notification, Worker, crypto, localStorage. Every one is an entire subsystem you can program.
The single main thread
JavaScript runs on a single main thread in the browser. That same thread also handles:
- Parsing HTML and CSS
- Running event handlers
- Layout calculations
- Painting
If your JS blocks the thread for 200ms, nothing else can happen — the page becomes unresponsive. This is the single biggest source of "janky" feeling web pages.
Web Workers let you run JS on background threads, but workers can't access the DOM. They're useful for heavy computation (image processing, parsing large files, running ML models).
A 60fps animation needs the browser to render a frame every 16.6 milliseconds. If a JavaScript callback takes longer than 16ms on the main thread, you'll drop a frame — the animation visibly stutters. This is why performance engineers obsess over keeping callbacks short and moving heavy work to Web Workers, requestIdleCallback, or the server.
Common mistakes
- Confusing Service Workers with Web Workers. They sound similar and they're nothing alike. Web Workers run JS on a background thread (for CPU work). Service Workers are a programmable network proxy that survives the page closing (for offline, push, caching). Picking the wrong one wastes a day.
- Storing large or sensitive data in
localStorage. It's ~5MB max, synchronous (blocks the main thread), and readable by any script on the page. For anything bigger or richer than tiny preferences, use IndexedDB. For secrets, use an HttpOnly cookie —localStorageis fully exposed to XSS. - Reaching for
setTimeout(fn, 0)to "yield to the browser." It mostly works but it's a stale pattern. Modern code usesqueueMicrotask,requestAnimationFrame,requestIdleCallback, orscheduler.postTaskdepending on whether you need "before next paint," "during idle," or "next tick." Each has different timing guarantees. - Mutating the DOM in a hot loop. Each
el.style.left = ...can trigger layout, and the cost compounds. Read all the layout values first, then write — or batch updates withrequestAnimationFrame. Tools like the Performance panel will flag "forced reflow" warnings when you get this wrong. - Assuming
window.crypto.randomUUID()and friends work everywhere. Most modern Web APIs require a secure context (HTTPS orlocalhost). Open the page overhttp://from a LAN IP and half the APIs silently disappear. If something works onlocalhostbut not your staging URL, check HTTPS first.
Page checkpoint
Did the browser runtime stick?
RequiredWhat's next
→ Continue to The Rendering Pipeline where we'll trace exactly how HTML becomes pixels, and why some CSS properties are 60fps smooth while others stutter.