Skip to content

Workbox

In one line: Workbox is Google’s production-grade service worker library. It replaces hand-rolled fetch event logic with composable modules for routing, caching strategies, precaching, background sync, and expiration — while staying close to the raw Service Workers API.

Module Purpose
workbox-routing Route fetch events to different handlers by URL pattern or request property
workbox-strategies CacheFirst, NetworkFirst, StaleWhileRevalidate, NetworkOnly, CacheOnly implementations
workbox-precaching Manifest-driven precaching with integrity verification and cache cleanup
workbox-expiration Bound cache size and TTL on any cache
workbox-cacheable-response Filter cacheable responses by status code or header
workbox-background-sync Queue failed POST requests and replay when connectivity returns
workbox-broadcast-update Notify pages when a cached response is updated
workbox-google-analytics Buffer offline analytics events and replay on reconnect
sw.js
import { registerRoute } from 'https://cdn.jsdelivr.net/npm/workbox-routing@7/registerRoute.mjs';
import { CacheFirst } from 'https://cdn.jsdelivr.net/npm/workbox-strategies@7/CacheFirst.mjs';
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({ cacheName: 'images' })
);
Terminal window
npm install workbox-routing workbox-strategies workbox-precaching
// sw.js (bundled)
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst } from 'workbox-strategies';
Terminal window
npm install workbox-window
import { Workbox } from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
// Listen for an update and notify the user
wb.addEventListener('waiting', () => {
if (confirm('New version available. Reload?')) {
wb.messageSkipWaiting();
window.location.reload();
}
});

workbox-window handles registration, update detection, and skipWaiting messaging — the boilerplate that otherwise lives in every page.

Precaching uses a manifest (generated at build time) to cache a list of versioned URLs. Workbox tracks the manifest hash and only re-fetches entries whose content has changed:

import { precacheAndRoute } from 'workbox-precaching';
// __WB_MANIFEST is injected by the Workbox build tool (injectManifest / generateSW)
precacheAndRoute(self.__WB_MANIFEST);

Build tools that produce this manifest: workbox-webpack-plugin (via InjectManifest or GenerateSW), workbox-vite-plugin, workbox-cli, and @ducanh2912/next-pwa.

import { registerRoute, NavigationRoute } from 'workbox-routing';
import { NetworkFirst, CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { ExpirationPlugin } from 'workbox-expiration';
// Pages (SPA and MPA)
registerRoute(
new NavigationRoute(new NetworkFirst({ cacheName: 'pages' }))
);
// Images with expiration
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
cacheName: 'images',
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
new ExpirationPlugin({ maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 }),
],
})
);
// Fonts — stale-while-revalidate, long-lived
registerRoute(
({ request }) => request.destination === 'font',
new StaleWhileRevalidate({ cacheName: 'fonts' })
);
Mode What Workbox does When to use
GenerateSW Generates a complete sw.js from your config Simple apps; no custom logic needed in the worker
InjectManifest Injects the precache manifest into your own sw.js template You need custom routing, background sync, or any code beyond precaching
  • Workbox does not write the manifest or handle code-splitting — that is your bundler’s job.
  • It does not provide a push notification API — use the native Web Push API directly.
  • Background sync in Workbox uses BackgroundSyncPlugin, which relies on the Background Sync API (not yet available in Safari as of this writing).
  • Pin Workbox to a specific major version (workbox-routing@7) — avoid floating @latest in production.
  • Use InjectManifest if you need any custom routing or background sync logic in the worker.
  • Use workbox-window in the page for clean registration, update prompts, and skipWaiting coordination.
  • Add ExpirationPlugin to every CacheFirst route to bound cache growth.
  • Test with DevTools → Application → Service Workers → “Update on reload” to exercise precache revision logic.