Stop Installing Libraries: 10 Browser APIs That Already Solve Your Problems

Published: (February 4, 2026 at 06:05 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

The web platform is more powerful than most developers realize, and every year it quietly gains new super‑powers. Below are ten under‑used browser APIs that can save you from pulling in external libraries and make your code cleaner, faster, and more reliable.

Structured Clone (structuredClone)

A one‑liner deep copy that handles most built‑in types, including Map, Set, Date, Blob, File, and ArrayBuffer. It also copes with circular references (no more JSON‑stringify explosions) but does not clone functions.

const copy = structuredClone(original);

Support: Modern browsers (Chrome, Firefox, Safari, Edge). Safe for production.

Performance API (performance.mark / performance.measure)

Great for micro‑benchmarks, checking whether a Web Worker or WASM is worth the overhead, or simply reality‑checking assumptions.

performance.mark('start');

// code to measure

performance.mark('end');
performance.measure('calc', 'start', 'end');

console.log(performance.getEntriesByName('calc'));

Support: Excellent across all modern browsers.

Page Visibility API

Detect when the tab becomes hidden or visible, allowing you to pause videos, stop polling, or reduce CPU usage.

document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    video.pause();
  }
});

Support: All modern browsers.

ResizeObserver

Observe size changes of any element—not just the window—making responsive components, charts, and dashboards far easier to implement.

const ro = new ResizeObserver(entries => {
  for (const entry of entries) {
    console.log(entry.contentRect.width);
  }
});

ro.observe(element);

Support: Modern browsers, widely available.

IntersectionObserver

Detect when an element enters or leaves the viewport, perfect for infinite scroll, lazy loading, and scroll‑based animations.

const io = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('Visible!');
    }
  });
});

io.observe(element);

Support: All modern browsers.

AbortController

Cancel fetch requests and any other abortable API (e.g., streams, event listeners) with a clean, scalable pattern.

const controller = new AbortController();

fetch(url, { signal: controller.signal })
  .catch(err => {
    if (err.name === 'AbortError') console.log('Fetch aborted');
  });

// later
controller.abort();

Support: All modern browsers.

IdleDetector

Detect when the user (or the device) is idle, enabling auto‑logout, “away” status, or background optimizations.

const detector = new IdleDetector();

await detector.start();

detector.addEventListener('change', () => {
  console.log(detector.userState); // "active", "idle", etc.
});

Support: Mostly Chromium‑based browsers; requires user permission.

BroadcastChannel

Simple, multi‑tab communication without a server round‑trip.

const channel = new BroadcastChannel('app');

channel.postMessage('logout');

channel.onmessage = e => {
  console.log(e.data);
};

Support: Modern browsers (Safari added support later).

Web Locks API

Coordinate shared resources across tabs, preventing duplicate work such as multiple fetches for the same data.

navigator.locks.request('data-lock', async lock => {
  await fetchData(); // only one tab runs this at a time
});

Support: Mostly Chromium; not universal yet.

File System Access API

Give web apps real file‑system capabilities—ideal for editors, import/export tools, and power‑user applications.

const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();

Support: Chromium‑heavy browsers; limited elsewhere.

Closing thoughts

Most of these APIs are well supported in modern browsers, but always double‑check compatibility before committing to them. Knowing they exist can dramatically reduce the need for third‑party libraries and keep your codebase lean.

What’s your favorite underrated Web API that nobody talks about?

(If you’re in Italy this April, catch my talk on WebGPU + WASM at jsday.it.)

Back to Blog

Related posts

Read more »

Replace Turbo confirm with native dialog

Rails, when using turbo‑links, ships with a built‑in confirmation dialog for destructive actions. You've probably used it countless times: erb The default turbo...