10LOC

Chrome APIs

Chrome APIsadvanced

Shared Storage: privacy-preserving experiments, now being retired

type SharedStorage = {
  worklet: { addModule: (url: string) => Promise<void> };
  set: (key: string, value: string, options?: { ignoreIfPresent?: boolean }) => Promise<void>;
  run: (operation: string, options?: { data?: Record<string, unknown> }) => Promise<void>;
};

How the Shared Storage API worked for cross-site experiments without third-party cookies — and why Chrome is deprecating and removing it.

Chrome APIsadvanced

Periodic Background Sync for resilient refresh jobs

type PeriodicSyncRegistration = ServiceWorkerRegistration & {
  periodicSync: { register: (tag: string, options: { minInterval: number }) => Promise<void> };
};

export const schedulePeriodicRefresh = async (tag: string, minIntervalMs: number): Promise<boolean> => {

Schedule light refresh work that can survive transient network loss.

Chrome APIsadvanced

The File Handling API for browser file access

type LaunchParams = { files: FileSystemFileHandle[] };
type LaunchQueue = { setConsumer: (consumer: (params: LaunchParams) => void) => void };

export const handleLaunchedFiles = (onFiles: (files: File[]) => void): void => {
  const launchQueue = (window as { launchQueue?: LaunchQueue }).launchQueue;

Open and work with files directly from the browser with the File Handling API.

Chrome APIsintermediate

Background Sync for offline-friendly actions

type SyncRegistration = ServiceWorkerRegistration & { sync: { register: (tag: string) => Promise<void> } };

export const scheduleOfflineAction = async (tag: string, replayNow: () => Promise<void>): Promise<void> => {
  const registration = await navigator.serviceWorker.ready;
  const canBackgroundSync = "sync" in registration;

Replay user actions later when connectivity returns with Background Sync.

Chrome APIsadvanced

The Speculation Rules API to prerender the next likely page

const injectedUrls = new Set<string>();

export const prerenderOnHoverIntent = (link: HTMLAnchorElement, dwellMs = 200) => {
  if (!(globalThis as any).HTMLScriptElement?.supports?.("speculationrules")) return;
  let timer = 0;

A dynamically-injected <script type=speculationrules> can prerender a hovered link in the background, so the click lands on an already-rendered page.

Chrome APIsintermediate

console.table and console.time power tricks for real debugging

type Row = { id: number; status: string; durationMs: number };

export const logBatchResult = async (rows: Row[], errors: { field: string; message: string }[]) => {
  console.table(rows, ["id", "status", "durationMs"]);

console.table renders records as a sortable grid instead of a collapsed tree, and console.time/timeLog/count turn ad-hoc timing into two-line instrumentation.

Chrome APIsintermediate

content-visibility: auto to skip render cost offscreen

.long-page section {
  content-visibility: auto;
  contain-intrinsic-size: auto 480px;
}

content-visibility: auto skips layout, style, and paint for an off-screen subtree — near-free virtualization that keeps find-in-page and anchors working.

Chrome APIsadvanced

WebCodecs for low-level video frame processing

// @types/dom-webcodecs isn't installed in this repo, so VideoDecoder/VideoFrame/
// EncodedVideoChunk aren't typed here — cast to `any` rather than pretend otherwise.
export const decodeFrames = (chunks: any[], onFrame: (frame: any) => void): Promise<void> => {
  const Decoder = (globalThis as any).VideoDecoder;
  const decoder = new Decoder({

VideoDecoder exposes the browser's own hardware decoder as a queue: feed chunks in, get real VideoFrame objects out — no ffmpeg.wasm, no <video> polling.

Chrome APIsintermediate

URLPattern for route matching without a regex library

// TypeScript hasn't bundled URLPattern into its DOM types yet, so this repo's tsconfig
// doesn't know about it either. One cast at the constructor keeps everything below fully
// typed instead of leaking `any` through the rest of the file.
type UrlMatch = { pathname: { groups: Record<string, string | undefined> } };
type UrlPatternLike = { exec: (input: { pathname: string }) => UrlMatch | null };

URLPattern standardizes the :param/wildcard matching every router library reinvents — built into the browser and, increasingly, server runtimes too.

Chrome APIsintermediate

text-wrap: balance for balanced headlines with no JS

h1, h2, .card-title {
  text-wrap: balance;
  max-width: 40ch;
}

text-wrap: balance redistributes a heading's line breaks evenly instead of greedy fill — computed by the layout engine, re-balanced on every resize.

Chrome APIsadvanced

Declarative Shadow DOM for server-rendered web components

<user-card>
  <template shadowrootmode="open">
    <style>
      :host { display: block; border: 1px solid #ddd; border-radius: 8px; padding: 1rem; }
      .name { font-weight: 600; margin: 0; }

A <template shadowrootmode> is parsed straight into a real shadow root by the HTML parser — a web component's shadow tree, fully rendered before any JS runs.

Chrome APIsintermediate

The inert attribute to trap focus outside a modal

export const openModal = (modalRoot: HTMLElement) => {
  const siblings = Array.from(document.body.children).filter(
    (el): el is HTMLElement => el !== modalRoot && el instanceof HTMLElement,
  );
  siblings.forEach((el) => {

Setting .inert on everything outside a custom modal removes it from tab order, clicks, and the a11y tree in one line — no focus-trap library.

Chrome APIsintermediate

CSS @starting-style for entry animations with no JS

.toast {
  display: none;
  opacity: 0;
  translate: 0 12px;
  transition: opacity 0.2s ease, translate 0.2s ease, display 0.2s allow-discrete;

@starting-style supplies the missing before-state so a CSS transition can animate an element's first render — no class-added-next-frame trick, no library.

Chrome APIsadvanced

A minimal WebGPU compute shader

// No @webgpu/types in this repo's tsconfig, so these casts stand in for the
// missing ambient types. Swap them for the real types in a project that has
// @webgpu/types installed.
export const doubleOnGpu = async (input: Float32Array): Promise<Float32Array> => {
  const gpu = (navigator as any).gpu;

WebGPU's compute pipeline runs a WGSL kernel across GPU threads in parallel from a buffer you own — general-purpose GPU compute, not just triangles.

Chrome APIsadvanced

The File System Access API for native file read/write

// TypeScript's DOM lib has FileSystemFileHandle but not window.showOpenFilePicker
// itself yet -- narrow cast for just the missing entry point.
type ShowOpenFilePicker = (opts: {
  types: { description: string; accept: Record<string, string[]> }[];
}) => Promise<FileSystemFileHandle[]>;

showOpenFilePicker and createWritable read and overwrite a real file on disk from the browser — Chromium only, no Firefox or Safari support.

Chrome APIsadvanced

The Navigation API for SPA routing without a router library

// TypeScript's DOM lib has neither URLPattern nor the Navigation API yet --
// narrow casts for just the shapes this snippet actually uses.
type UrlMatch = { pathname: { groups: Record<string, string | undefined> } };
type UrlPatternLike = { test: (i: { pathname: string }) => boolean; exec: (i: { pathname: string }) => UrlMatch | null };
const URLPattern = (globalThis as any).URLPattern as new (init: { pathname: string }) => UrlPatternLike;

navigation.addEventListener('navigate', ...) intercepts every link click and history change from one place — the primitive most routers wrap.

Chrome APIsadvanced

scheduler.postTask to yield to the main thread under load

type TaskPriority = "user-blocking" | "user-visible" | "background";
type PostTask = (cb: () => void, opts?: { priority?: TaskPriority }) => Promise<void>;

const postTask = (globalThis as { scheduler?: { postTask: PostTask } }).scheduler?.postTask;

scheduler.postTask breaks a long loop into prioritized chunks with real cancellation — a purpose-built replacement for setTimeout(fn, 0).

Chrome APIsintermediate

<dialog> for an accessible modal with zero JS libraries

<button id="delete-trigger">Delete project</button>

<dialog id="confirm-dialog" closedby="any" aria-labelledby="confirm-title">
  <form method="dialog">
    <h2 id="confirm-title">Delete this project?</h2>

showModal(), ::backdrop, and closedby give a modal focus-trapping, Esc-to-close, and light-dismiss — no react-modal, no focus-trap package.

Chrome APIsintermediate

The Popover API for a dismissible popover, no positioning library

// togglePopover's { source } option is current spec but not yet in TypeScript's DOM lib.
type TogglePopover = (options?: { source?: HTMLElement; force?: boolean }) => void;
const menu = document.querySelector<HTMLElement>("#user-menu")!;
const trigger = document.querySelector<HTMLButtonElement>("#user-menu-trigger")!;

popover="auto" gives light-dismiss, Esc-to-close, and top-layer stacking for free — no click-outside listener, no z-index fights.

Chrome APIsintermediate

The View Transitions API for animated state changes

export const swapView = (activeEl: HTMLElement, render: () => void) => {
  if (!document.startViewTransition) {
    render();
    return;
  }

document.startViewTransition animates a DOM update with a browser-computed crossfade or morph — no keyframes, no FLIP technique, no library.