Skip to main content

🧰 Browser API Overview

A modern browser is not just a document viewer β€” it's a full application platform with hundreds of built-in capabilities. It can read your location, tap the camera, run code on background threads, and work offline. This lesson maps out the major families of Web APIs so you know what's on the shelf, then dives into two you'll actually reach for: Geolocation and Web Workers.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Describe the main categories of browser APIs and give an example of each
  • Use feature detection and progressive enhancement so code degrades gracefully
  • Read a user's position with the Geolocation API, handling permissions and errors
  • Move heavy computation off the main thread with a Web Worker
  • Know where to check browser support before shipping a capability

Estimated Time: 35–45 minutes  β€’  Difficulty: Intermediate

Hands-on: Build a capability-report page that detects and lists the APIs the current browser supports.

In This Lesson

What Are Browser APIs?

A Web API (Application Programming Interface) is a set of objects, methods, and events the browser exposes to your JavaScript. You don't install them β€” they ship inside the browser. When you write document.querySelector(...), fetch(...), or navigator.geolocation, you're calling browser APIs.

πŸ’‘ A useful analogy: Think of the browser as a Swiss Army knife. The knife is the platform; each fold-out tool β€” scissors, screwdriver, bottle opener β€” is an API. Your app picks the tools it needs, and it doesn't have to carry them itself.

Collectively these APIs let a web app do things that used to require a native install:

  • Read device hardware β€” camera, microphone, GPS, sensors
  • Store data on the client and work offline
  • Talk to servers over HTTP and real-time sockets
  • Run background threads and defer work until the network returns
  • Draw complex 2D/3D graphics and process audio

The Major Categories

There are far too many APIs to memorise, but they cluster into a handful of families. Learn the shape of the map first; you can always look up a specific method later.

mindmap root((Browser APIs)) DOM & Events Selecting & editing elements Event handling Web Components Storage Web Storage IndexedDB Cache API Network Fetch WebSockets Server-Sent Events Media & Graphics Canvas WebGL / WebGPU Web Audio Media Streams Device Access Geolocation Device Orientation Web Bluetooth Background & Performance Web Workers Service Workers Performance API Intersection Observer
CategoryWhat it's forRepresentative APIs
DOM & EventsRead and change the page; respond to inputquerySelector, addEventListener
StorageKeep data on the clientWeb Storage, IndexedDB, Cache
NetworkCommunicate with serversFetch, WebSocket, EventSource
Media & GraphicsDraw, render, capture audio/videoCanvas, WebGL, getUserMedia
Device AccessReach hardware and sensorsGeolocation, Bluetooth, Orientation
BackgroundDo work off the main threadWeb Workers, Service Workers

The browser platform has grown in waves: basic DOM scripting in the 1990s, Ajax (XMLHttpRequest) and canvas in the 2000s, the HTML5 wave (Geolocation, Web Storage, WebSockets) in the 2010s, and Service Workers, WebAssembly, and hardware APIs since. The trend line is clear β€” the gap between web and native keeps shrinking.

Feature Detection & Progressive Enhancement

Not every browser supports every API, and support changes over time. The professional habit is never to assume an API exists β€” you detect it first, then enhance. This is the opposite of the old, brittle practice of sniffing the user-agent string.

// Feature detection: ask "does this exist?" before using it
if ('geolocation' in navigator) {
  navigator.geolocation.getCurrentPosition(showPosition);
} else {
  showManualLocationInput(); // graceful fallback
}

// The same pattern for a newer capability
if ('share' in navigator) {
  await navigator.share({ title: 'Great article', url: location.href });
} else {
  showCustomShareDialog();
}

βœ… Progressive enhancement in three steps

  1. Ship a baseline that works everywhere (a plain link, a manual input).
  2. Detect the fancy capability at runtime.
  3. Layer it on only when present β€” nobody gets a broken experience.

When you're unsure whether something is safe to use, check Can I Use for a support matrix and MDN for the authoritative reference and its browser-compatibility tables.

Deep Dive: The Geolocation API

The Geolocation API returns the user's coordinates, powering maps, "stores near me", weather, and delivery tracking. Because location is sensitive, the browser always asks permission first and only works over HTTPS.

The three methods

  • getCurrentPosition() β€” one-shot: get the position once.
  • watchPosition() β€” subscribe to updates as the user moves; returns a watch ID.
  • clearWatch(id) β€” stop watching.

Callbacks receive a GeolocationPosition whose coords holds latitude, longitude, accuracy (in metres), and sometimes altitude, heading, and speed. Here's a modern, promise-wrapped version so you can use async/await:

// Wrap the callback API in a Promise for clean async/await
function getPosition(options) {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject, options);
  });
}

async function showLocation() {
  if (!('geolocation' in navigator)) {
    return console.warn('Geolocation not supported');
  }
  try {
    const pos = await getPosition({ enableHighAccuracy: true, timeout: 10_000 });
    const { latitude, longitude, accuracy } = pos.coords;
    console.log(`You are near ${latitude.toFixed(4)}, ${longitude.toFixed(4)} (Β±${accuracy}m)`);
  } catch (err) {
    // err.code tells you WHY it failed
    switch (err.code) {
      case err.PERMISSION_DENIED:    return console.log('User declined location access');
      case err.POSITION_UNAVAILABLE: return console.log('Position unavailable');
      case err.TIMEOUT:              return console.log('Location request timed out');
    }
  }
}

The permission flow is a small handshake between four parties. Understanding it explains why you sometimes see a prompt and sometimes don't (the browser remembers a prior decision):

sequenceDiagram participant Page as Your Page participant Browser participant User participant GPS as Device / GPS Page->>Browser: getCurrentPosition() Browser->>User: Show permission prompt User->>Browser: Allow Browser->>GPS: Request coordinates GPS-->>Browser: latitude, longitude, accuracy Browser-->>Page: GeolocationPosition

⚠️ Ask at the right moment

Don't request location on page load "just in case." Prompt only when the user does something that clearly needs it (taps "Find stores near me"), and explain why first. An unexplained prompt is almost always denied β€” and a denial can be sticky.

Deep Dive: Web Workers

JavaScript on a page runs on a single thread β€” the same one that handles clicks, scrolling, and rendering. A long calculation blocks that thread, freezing the whole UI. Web Workers fix this by running scripts on a separate background thread, keeping the page responsive.

Main thread vs. worker thread The main thread handles the UI and events while communicating by messages with a separate worker thread that performs heavy computation. Main thread DOM & rendering User events Stays responsive βœ“ Worker thread Heavy computation No DOM access Runs in parallel postMessage() onmessage
Figure 1 β€” The main thread and worker communicate only by passing messages. The worker can't touch the DOM, but it can crunch numbers without freezing the page.

A worker lives in its own file. The two sides talk exclusively through postMessage() and the message event β€” data is copied between them (structured cloning), never shared directly.

// main.js β€” create the worker and talk to it
const worker = new Worker('primes.worker.js');

document.querySelector('#run').addEventListener('click', () => {
  status.textContent = 'Working…';
  worker.postMessage({ limit: 5_000_000 }); // hand off the heavy job
});

worker.addEventListener('message', (e) => {
  status.textContent = `Found ${e.data.count} primes`;
});

worker.addEventListener('error', (e) => {
  status.textContent = 'Worker error: ' + e.message;
});
// primes.worker.js β€” runs on its own thread
self.addEventListener('message', (e) => {
  const { limit } = e.data;
  let count = 0;
  for (let n = 2; n < limit; n++) {
    let prime = true;
    for (let d = 2; d * d <= n; d++) {
      if (n % d === 0) { prime = false; break; }
    }
    if (prime) count++;
  }
  self.postMessage({ count }); // send the result back
});

⚠️ Worker limitations

  • No DOM access β€” a worker can't read or change the page directly. Send results back and let the main thread update the UI.
  • No window, document, or alert; the global object is self.
  • Copying large data has a cost. For big binary buffers, use transferable objects to hand off ownership with zero copy: worker.postMessage(buf, [buf]).

Web Workers are ideal for image filtering, parsing large files, cryptography, or any CPU-bound loop. Their cousin, the Service Worker, is a specialised worker that sits between your page and the network to enable offline support and push notifications β€” a topic worth a lesson of its own.

Emerging APIs

The platform keeps growing. These are newer and less universally supported β€” always feature-detect and provide a fallback before relying on them:

APIWhat it enablesDetect with
File System AccessOpen and save real files on the user's disk'showOpenFilePicker' in window
Web BluetoothTalk to nearby Bluetooth devices'bluetooth' in navigator
WebGPUModern GPU compute & graphics'gpu' in navigator
WebXRVirtual and augmented reality'xr' in navigator
Web ShareInvoke the native share sheet'share' in navigator

A tidy way to survey what the current browser supports is to build a capabilities map β€” the exact idea behind this lesson's exercise:

const capabilities = {
  geolocation:   'geolocation' in navigator,
  webWorkers:    typeof Worker !== 'undefined',
  serviceWorker: 'serviceWorker' in navigator,
  webShare:      'share' in navigator,
  bluetooth:     'bluetooth' in navigator,
  fileSystem:    'showOpenFilePicker' in window,
  webGPU:        'gpu' in navigator
};
console.table(capabilities);

Best Practices

βœ… Do

  • Feature-detect every non-trivial API before using it.
  • Handle errors β€” network APIs fail, permissions get denied. Distinguish a TypeError (network) from a bad HTTP status.
  • Throttle or debounce handlers for frequent events (scroll, resize) and use { passive: true } listeners.
  • Release resources β€” stop media tracks, terminate() idle workers, clearWatch() geolocation.
  • Ask for permission in context, with a clear reason.

⚠️ Don't

  • Don't sniff the user-agent to decide what's supported β€” detect the feature itself.
  • Don't request sensitive permissions on page load.
  • Don't do CPU-heavy loops on the main thread β€” hand them to a worker.
  • Don't assume an API that works in your browser works in everyone's.
// Distinguishing failure modes when calling a network API
async function loadData(url) {
  try {
    const res = await fetch(url);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    if (err instanceof TypeError) console.error('Network/offline error', err);
    else console.error('Request failed', err);
    return null; // fall back gracefully
  }
}

Hands-on Exercise

πŸ‹οΈ Build a Browser Capability Report

Objective: Practise feature detection by generating a live report of what the current browser supports.

Instructions:

  1. Create a page with an empty <ul id="report"></ul>.
  2. Build an object that tests for at least six APIs (Geolocation, Web Workers, Service Worker, Web Share, Clipboard, and one emerging API of your choice).
  3. For each entry, append a list item showing the API name and a βœ… or ❌ based on support.
  4. Add one interactive demo: a button that, if navigator.share exists, opens the native share sheet, and otherwise shows a "copied link" fallback using the Clipboard API.
  5. Stretch: for Geolocation, actually request the position on a button click and print the coordinates, handling a denial cleanly.
πŸ’‘ Hint

Every detection is just 'name' in navigator or 'name' in window β€” no try/catch needed for the check itself. Loop over Object.entries() of your capabilities object to build the list.

βœ… Sample solution
const caps = {
  Geolocation:    'geolocation' in navigator,
  'Web Workers':  typeof Worker !== 'undefined',
  'Service Worker':'serviceWorker' in navigator,
  'Web Share':    'share' in navigator,
  Clipboard:      'clipboard' in navigator,
  'File System':  'showOpenFilePicker' in window
};

const report = document.querySelector('#report');
for (const [name, supported] of Object.entries(caps)) {
  const li = document.createElement('li');
  li.textContent = `${supported ? 'βœ…' : '❌'} ${name}`;
  report.appendChild(li);
}

document.querySelector('#share').addEventListener('click', async () => {
  const data = { title: document.title, url: location.href };
  if (navigator.share) {
    try { await navigator.share(data); } catch { /* user cancelled */ }
  } else if (navigator.clipboard) {
    await navigator.clipboard.writeText(location.href);
    alert('Link copied to clipboard!');
  }
});

🎯 Quick Quiz

Question 1: What is the recommended way to decide whether to use a browser API?

Question 2: Why move a long calculation into a Web Worker?

Question 3: Which is true of the Geolocation API?

Summary & Quiz

πŸŽ‰ Key Takeaways

  • Web APIs ship inside the browser and turn it into an application platform.
  • They cluster into families: DOM, Storage, Network, Media/Graphics, Device Access, Background.
  • Always feature-detect and progressively enhance β€” baseline first, fancy layer second.
  • Geolocation needs HTTPS and permission; wrap its callbacks in a Promise for clean async code.
  • Web Workers run heavy work off the main thread and talk via postMessage β€” no DOM access.
  • Check Can I Use and MDN before shipping any non-universal capability.

πŸ“š Further Reading

πŸš€ What's Next?

We touched the navigator object throughout this tour. Next we'll zoom into two of the most everyday browser objects β€” Navigator and Location β€” to read browser and connection info and to inspect and manipulate the URL.

πŸŽ‰ Great work!

You've got the map of the browser platform. Let's zoom into the objects you'll use daily.