Use Workbox

Use Workbox when handwritten service worker code is becoming a cache invalidation project.

Choose A Mode

ModeUse whenTrade-off
generateSWYou need precaching and straightforward runtime cachingLess custom service worker control
injectManifestYou need custom push, sync, routing, or complex offline behaviorMore code and lifecycle responsibility

Vite PWA Shape

import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    VitePWA({
      registerType: 'prompt',
      strategies: 'generateSW',
      manifest: {
        name: 'Ledger',
        short_name: 'Ledger',
        start_url: '/',
        scope: '/',
        display: 'standalone',
        theme_color: '#0f172a',
        background_color: '#ffffff',
        icons: [
          { src: '/icons/icon-192.png', sizes: '192x192', type: 'image/png' },
          { src: '/icons/icon-512.png', sizes: '512x512', type: 'image/png' },
          { src: '/icons/icon-maskable.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
        ],
      },
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
        runtimeCaching: [
          {
            urlPattern: /^https:\/\/api\.example\.com\/reference\//,
            handler: 'StaleWhileRevalidate',
            options: {
              cacheName: 'reference-data',
              expiration: { maxEntries: 50, maxAgeSeconds: 60 * 60 * 24 },
            },
          },
        ],
      },
    }),
  ],
});

Use injectManifest When

  • You need custom notification click routing.
  • You need explicit offline mutation replay.
  • You need custom cache migration.
  • You need to coordinate service worker updates with app UI.

Gotcha: Workbox reduces boilerplate. It does not remove the need to define freshness, privacy, cache size, and update rules.