Modern JavaScript includes built-in APIs that handle tasks once left to libraries. Many are fast, dependency-free, and production-ready in most browsers.
Browser support varies, some (BroadcastChannel, PerformanceObserver) work everywhere, while others (File System Access, View Transitions) need Safari polyfills or progressive enhancement.
Below are seven underused APIs. What they do, why they matter, when to reach for them, and what to watch out for.
1. BroadcastChannel
What it is: A same-origin messaging system between browser contexts (tabs, iframes, workers).
// Tab A
const ch = new BroadcastChannel('cart');
ch.postMessage({ type: 'ITEM_ADDED', id: 42 });
// Tab B
const ch2 = new BroadcastChannel('cart');
ch2.onmessage = (e) => console.log(e.data);
Why it matters: Eliminates the pain of syncing state between tabs, removing localStorage hacks (polling overhead, stale reads) and postMessage boilerplate (origin checks, serialization dance). This means cleaner code and fewer sync bugs.
When to use it: Multi-tab coordination, cart updates, live notifications, or preventing duplicate sessions.
Watch out for: Messages don’t persist, if no tab is listening, they’re lost.
2. PerformanceObserver
What it is: A live stream of performance entries. Measures, long tasks, LCP, CLS, and more.
const po = new PerformanceObserver((list) => {
list.getEntries().forEach(e => sendPerf(e));
});
po.observe({ entryTypes: ['measure', 'longtask', 'resource'] });
performance.mark('t-start');
// ...
performance.mark('t-end');
performance.measure('init', 't-start', 't-end');
Why it matters: Provides actionable performance insights from the browser, so you can diagnose real user bottlenecks and justify optimization work with data.
When to use it: Real User Monitoring (RUM), SPA route profiling, or measuring feature load time in production.
Watch out for: Some entries (like LCP/CLS) depend on the Performance Timeline API, test before relying on full coverage.
3. Web Locks API
What it is: A cooperative locking system that prevents concurrent work across tabs or workers.
await navigator.locks.request('sync-inventory', async () => {
await doCriticalSync(); // only one context runs this at a time
});
Why it matters: Prevents hard-to-reproduce bugs caused by concurrent operations stepping on each other, crucial for reliability and data integrity.
When to use it: Background sync, cache writes, or migration steps that must run exactly once.
Watch out for: Works across tabs but not across devices, don’t use it as a distributed lock.
4. ReportingObserver
What it is: An API that captures browser-generated reports, deprecations, interventions, and runtime warnings.
const observer = new ReportingObserver((reports) => {
for (const r of reports) sendToTelemetry(r.type, r.body);
}, { types: ['deprecation', 'intervention'], buffered: true });
observer.observe();
Why it matters: Gives your QA and production telemetry early warning when browser behavior changes, which helps catch silent breakage.
When to use it: Monitor production deprecations, detect browser policy changes, and surface silent errors.
Watch out for: Not all browsers emit the same report types, validate coverage before using as your only alert source.
5. Compression Streams
What it is: Native gzip and deflate compression via CompressionStream and DecompressionStream, streaming and zero dependencies.
async function gzipString(str) {
const cs = new CompressionStream('gzip');
const stream = new Blob([str]).stream().pipeThrough(cs);
return new Response(stream).arrayBuffer();
}
Why it matters: Shrinks large payloads before upload or download, saving bandwidth and time, especially valuable for export-heavy apps and analytics tooling.
When to use it: Exporting logs, compressing uploads, or packaging large JSON blobs.
Watch out for: Browser decompression is fast, but compression can block the main thread for large payloads, offload to a worker if possible.
6. File System Access API
What it is: Direct read/write access to local files with explicit user permission.
const handle = await window.showSaveFilePicker({ suggestedName: 'data.json' });
const writable = await handle.createWritable();
await writable.write(JSON.stringify(data));
await writable.close();
Why it matters: Enables desktop-like experiences: instant saves and offline workflows that make web apps feel native.
When to use it: Code editors, design tools, note-taking apps, or any product that manipulates files locally.
Watch out for: Requires user gestures and permissions (requires a Safari polyfill).
7. View Transitions API
Chrome and Edge supported; Safari and Firefox in development
What it is: Native, CSS-driven route and DOM transitions with shared element animations.
await document.startViewTransition(async () => {
renderNextView(); // mutate DOM here
});
Why it matters: Makes SPA navigation feel instant and intentional. This polish keeps users engaged and reduces perceived load time.
When to use it: SPA navigation, list-to-detail transitions, or any DOM swap needing visual continuity.
Watch out for: Progressive enhance only, fallback to no animation on unsupported browsers.
Honorable Mentions
-
AbortController /
AbortSignal.timeout(): Cancel fetches, timers, and custom async work cleanly. - OffscreenCanvas: Move rendering off the main thread for smoother UIs.
- Navigation API: Native SPA routing primitives replacing custom history hacks.
The Bottom Line
BroadcastChannel and PerformanceObserver are widely supported and address common sync and performance problems. Add View Transitions and File System Access as progressive enhancements.
Top comments (0)