Skip to content

Tooling and frameworks

PWA tooling automates the parts of a progressive web app that are tedious and easy to get wrong by hand. That means generating a revisioned precache manifest on every build, writing and bundling the service worker, producing dozens of icon and splash-screen sizes, and packaging the app for app stores. Almost every mainstream tool in 2026 is built on the same core: Workbox, or its fork Serwist. That shared ancestry is why their options, cache names and failure modes look so alike. This section documents the tools in depth. This page maps the landscape and helps you choose.

Key takeaways

  • Workbox (7.4.1, May 2026) is the foundation of most PWA tooling. Chrome's Aurora team owns it, and its 7.x releases since 2023 have been maintenance only: the API is stable and feature-frozen.
  • Serwist (9.5.12, July 2026) is an actively developed, ESM-only Workbox fork. It is the most maintained PWA integration path for Next.js, and it also covers Vite, Nuxt, SvelteKit and webpack.
  • vite-plugin-pwa (1.3.0, May 2026) wraps workbox-build for any Vite-based stack. Its sibling packages cover Nuxt, SvelteKit and Astro.
  • Some frameworks ship their own service worker story: Angular's @angular/service-worker and SvelteKit's built-in src/service-worker support. Next.js documents a manual approach.
  • PWABuilder packages a live PWA for the Microsoft Store, Google Play (through Bubblewrap and Trusted Web Activities) and, experimentally, the Apple App Store.
  • Lighthouse removed its PWA category in version 12.0 (2024). Installability and offline behavior are now tested with DevTools, Playwright and custom checks.

The PWA toolchain in layers

A PWA toolchain has six layers. Most projects use tools from three or four of them.

flowchart TD
    A["Service worker runtime: Workbox or Serwist libraries, or hand-written code"] --> B["Build integration: workbox-build / CLI / webpack plugin, vite-plugin-pwa, @serwist/*"]
    B --> C["Framework integration: @vite-pwa/nuxt, @vite-pwa/sveltekit, @serwist/next, @angular/service-worker"]
    D["Assets and manifest: @vite-pwa/assets-generator, pwa-asset-generator"] --> C
    C --> E["Deploy to the web (HTTPS)"]
    E --> F["Packaging and distribution: PWABuilder, Bubblewrap"]
    E --> G["Testing and auditing: DevTools, Playwright, Lighthouse"]
Layer What it produces Main tools Where it's covered
Runtime Routing, caching strategies, precaching, expiration, background sync code inside sw.js Workbox runtime modules, Serwist Workbox fundamentals, Advanced Workbox
Build integration The precache manifest; the bundled worker workbox-build, workbox-cli, workbox-webpack-plugin, vite-plugin-pwa, @serwist/build Workbox fundamentals, Vite PWA plugin
Framework integration Zero-config wiring into a meta-framework's build and routing @vite-pwa/*, @serwist/next, @angular/service-worker, SvelteKit built-in Framework integrations
Assets and manifest Icons, maskable icons, Apple splash screens, favicons, manifest icons @vite-pwa/assets-generator, pwa-asset-generator Icons, Splash screens
Packaging Store packages (MSIX, Android App Bundle, Xcode project) PWABuilder, Bubblewrap CLI PWABuilder, Trusted Web Activity
Testing Automated checks for installability, offline behavior, updates Chrome DevTools, Playwright, Puppeteer, Lighthouse Testing and debugging

Versions at a glance

The versions below come from the npm registry on 25 September 2026. The dates are the publication dates of those versions.

Package Latest version Published Notes
workbox-build, workbox-window and all workbox-* modules 7.4.1 2026-05-04 Build tools require Node.js 20+ since 7.4.0
serwist, @serwist/next, @serwist/vite, @serwist/build, … 9.5.12 2026-07-22 ESM-only since 9.0.0; Next.js peer range >=14.0.0
vite-plugin-pwa 1.3.0 2026-05-05 Peer vite ^3.1.0 through ^8.0.0; depends on workbox-build ^7.4.1
@vite-pwa/nuxt 1.1.1 2026-02-06 Nuxt module around vite-plugin-pwa
@vite-pwa/sveltekit 1.1.0 2025-11-27 SvelteKit adapter
@vite-pwa/astro 1.2.0 2025-11-27 Astro integration
@angular/service-worker, @angular/pwa 22.2.0 2026-09-23 Versioned with Angular itself
@vite-pwa/assets-generator 2.0.0 2026-09-12 ESM-only since 2.0.0; Node.js 20.19+; uses sharp
pwa-asset-generator 8.1.7 2026-09-21 Renders with headless Chrome via puppeteer-core; Node.js 22.12+
@bubblewrap/cli 1.25.0 2026-07-31 Generates Trusted Web Activity Android projects; Node.js 18+
@khmyznikov/pwa-install 0.7.0 2026-09-14 <pwa-install> web component, listed by the PWABuilder project
lighthouse 13.5.0 2026-09-18 No PWA category since 12.0
@playwright/test 1.63.0 2026-09-04 Service worker network events on Chromium only
puppeteer 25.12.0 2026-09-23 Chrome/Firefox automation

Tooling versions change monthly. Check npm view <package> version before you copy a version range from any article, including this one.

Service worker libraries

You can write a service worker by hand. The service workers and caching sections of this site show exactly how. A library earns its place by handling the tedious edge cases correctly: revision-keyed precaching that only downloads changed files, cache: "reload" for unhashed URLs, copying redirected responses, opaque-response rules, LRU expiration metadata in IndexedDB, background-sync fallbacks, and lifecycle helpers for the page.

Hand-written Workbox 7 Serwist 9
Maintenance Yours Chrome Aurora team; dependency and security releases, no new runtime features since 2023 Community; regular releases, new features (e.g. experimental InstallEvent.addRoutes() rules)
API shape Whatever you design Many small modules (workbox-routing, workbox-strategies, …), function-based One serwist package, a Serwist class plus the same strategies and plugins
Build modes n/a generateSW (config only) and injectManifest (your code) injectManifest only; the Serwist class replaces generateSW
Module format Any ESM source, CommonJS build tools ESM-only
Precache concurrency Yours One entry at a time 10 concurrent requests by default
Ecosystem n/a vite-plugin-pwa, many framework plugins, CLI wizard @serwist/next, @serwist/vite, @serwist/nuxt, @serwist/svelte, @serwist/webpack-plugin, @serwist/cli
Best for Small workers, learning, unusual requirements Stability, existing codebases, Vite projects via vite-plugin-pwa Next.js, teams wanting ESM and active development

A realistic Workbox worker bundles to about 30 KB minified, or under 10 KB gzipped. Advanced Workbox lists measured sizes. That is small next to most apps, but it isn't nothing for a site that only needs an offline page. A 60-line hand-written worker is a perfectly professional choice for that case.

Build integrations

Every build integration does two jobs: it produces a precache manifest (a list of {url, revision} entries, where the revision is a content hash) and gets it into the worker, and it bundles the worker. The differences are in how much of the worker it writes for you:

  • workbox-build / workbox-cli / workbox-webpack-plugin. generateSW writes the whole worker from configuration. injectManifest replaces self.__WB_MANIFEST in a worker you wrote. The CLI adds an interactive workbox wizard. Workbox fundamentals covers every option.
  • vite-plugin-pwa. Wraps workbox-build's two modes (strategies: "generateSW" | "injectManifest") and adds what Vite users need: manifest generation and injection, a virtual registration module (virtual:pwa-register plus React, Vue, Svelte, Solid and Preact variants) with prompt or autoUpdate behavior, a development-mode service worker, and integration with @vite-pwa/assets-generator. See Vite PWA plugin.
  • Serwist build packages. @serwist/build, @serwist/cli, @serwist/webpack-plugin and @serwist/vite all implement injectManifest with the self.__SW_MANIFEST injection point. Framework packages such as @serwist/next hide that step.

Whatever you use, the same few mistakes recur: precaching source maps or huge images, a navigation fallback without a denylist, skipWaiting in an SPA, and forgetting that the manifest only changes when content changes. Precaching and Updating service workers explain the mechanisms behind all four.

Framework integrations

Framework Recommended path (September 2026) What you get Notes
Vite + React / Vue / Svelte / Solid / Preact / vanilla vite-plugin-pwa Manifest, worker, registration hooks, dev worker Framework-specific registration hooks are virtual modules
Nuxt @vite-pwa/nuxt Nuxt module wrapping vite-plugin-pwa Replaces the Nuxt 2-era @nuxtjs/pwa
SvelteKit Built-in src/service-worker.js with the $service-worker module; or @vite-pwa/sveltekit for Workbox-based precaching Kit bundles and registers the worker; $service-worker exposes build, files, prerendered, version, base Built-in support is enough for many apps
Astro @vite-pwa/astro vite-plugin-pwa for Astro builds Static and hybrid output
Next.js @serwist/next (webpack builds) or @serwist/turbopack; or the manual approach in the official Next.js PWA guide Worker compiled from app/sw.ts, precache of build output, defaultCache runtime rules next-pwa and @ducanh2912/next-pwa are no longer maintained; the latter's README points to @serwist/next
Angular ng add @angular/pwa (adds @angular/service-worker) ngsw-worker.js driven by ngsw-config.json, SwUpdate and SwPush services Not Workbox-based; its own versioned-manifest design
Remix / React Router Hand-written worker or vite-plugin-pwa through the Vite build Varies Check the maintenance status of community packages before adopting them

Framework integrations has configuration, routing caveats (SSR navigation fallbacks, streaming, RSC payloads) and update handling for each.

Asset and manifest generators

The web app manifest and the platforms need many image variants: any and maskable icons at several sizes, an Apple touch icon, favicons, and on iOS a separate launch image for every device size and orientation. Two generators dominate:

  • @vite-pwa/assets-generator is a "zero-config" CLI and library. From one SVG or PNG it produces icons, maskable icons, Apple touch icons, favicons and optionally Apple splash screens, according to presets such as minimal2023Preset. It uses sharp (libvips), so it's fast and has no browser dependency. Version 2.0.0 (September 2026) is ESM-only and requires Node.js 20.19+. vite-plugin-pwa can run it during the build and inject the resulting <link> tags and manifest icons.
  • pwa-asset-generator renders its sources in headless Chrome through puppeteer-core. It can therefore take an HTML page or SVG with CSS as input and render splash screens with real layout. It can also rewrite your manifest.json and index.html with the generated entries. Version 8.x requires Node.js 22.12+.

Generated assets still need design review. The safe zone of a maskable icon is the central circle, with a radius of 40% of the icon size. See Icons and maskable icons and Splash screens and theming.

Packaging for app stores

A PWA doesn't need a store, but stores bring discoverability, and on some platforms installation habits. Two tools do the packaging:

  • PWABuilder is an open-source project hosted by Microsoft. You enter the URL of a deployed PWA. It audits the manifest and service worker, then generates packages: an MSIX for the Microsoft Store, an Android App Bundle for Google Play (a Trusted Web Activity generated with Bubblewrap), and an Xcode project for the Apple App Store, which its documentation labels experimental (a native Swift app hosting the PWA in a WebView). Store developer accounts are separate. Microsoft's current Partner Center onboarding flow charges no registration fee for individual or company accounts, Google Play charges a one-time $25 registration fee, and PWABuilder's App Store documentation notes Apple's $99-per-year developer program. The project also maintains the PWABuilder Studio extension for VS Code and a pwa-starter template, and lists the <pwa-install> web component.
  • Bubblewrap (@bubblewrap/cli, from Google Chrome Labs) is the command-line tool behind PWABuilder's Android packages. bubblewrap init --manifest=https://example.com/manifest.webmanifest generates an Android project from your manifest, and bubblewrap build produces a signed APK and App Bundle. You still have to publish /.well-known/assetlinks.json with your signing key's SHA-256 fingerprint. Without it the app shows a browser URL bar. See Trusted Web Activity.

Store packages load your live site, so a web deploy updates the app without a store resubmission. Changing the package itself (icons, name, signing key, Android API level) still requires one. Publishing to app stores covers review policies per store.

Testing and auditing tools

Tool Use it for PWA-relevant capabilities Limits
Chrome / Edge DevTools Interactive debugging Application panel: manifest parsing and installability errors, service worker lifecycle controls, Cache Storage, IndexedDB, background services, push/sync triggers Manual
Safari Web Inspector / Firefox DevTools Engine-specific bugs Service worker inspection, storage Fewer PWA-specific panels
Playwright End-to-end tests serviceWorkers: "allow" \| "block", context.serviceWorkers(), the serviceworker event, offline emulation, routing of worker requests Service worker network events and routing on Chromium only
Puppeteer Chrome automation, scripted audits CDP access to service worker targets, cache inspection Chrome-focused
Lighthouse 13 Performance, accessibility, SEO, best practices Measures a PWA's pages like any other page; offline and repeat-visit behavior only if you script it (e.g. user flows) No PWA category since 12.0 (April 2024); the installable-manifest, maskable-icon, splash-screen and themed-omnibox audits and the manifest/installability gatherers were removed with it

The PWA category was removed from Lighthouse 12.0. Its release notes cite Chrome's updated installability criteria and direct users to DevTools' PWA documentation instead. Installability and offline behavior are now best asserted in your own end-to-end tests: that the manifest is parsed, that beforeinstallprompt fires where it should, that the app shell loads offline, and that an update prompt appears after a deploy. See Automated testing and Lighthouse and auditing.

Choosing a toolchain

flowchart TD
    Q1{"Which framework?"}
    Q1 -->|"Next.js"| N["@serwist/next (or manual worker per Next.js guide)"]
    Q1 -->|"Angular"| A["ng add @angular/pwa"]
    Q1 -->|"Nuxt / SvelteKit / Astro / plain Vite"| V["vite-plugin-pwa or its framework package"]
    Q1 -->|"webpack app"| W["workbox-webpack-plugin (or @serwist/webpack-plugin)"]
    Q1 -->|"No bundler / static site generator"| S["workbox-cli generateSW, or a hand-written worker"]
    V --> Q2{"Need push, sync or custom routes?"}
    W --> Q2
    S --> Q2
    Q2 -->|"No"| G["generateSW-style configuration"]
    Q2 -->|"Yes"| I["injectManifest: write your own worker, let the tool inject the manifest"]

Some concrete guidance:

  • Content sites and documentation. A hand-written worker or workbox-cli generateSW with network-first pages, a precached offline page and cache-first images. Precache very little, and let runtime caching do the rest.
  • Single-page apps. vite-plugin-pwa or the webpack plugin, with a precached app shell, a navigateFallback with a strict denylist, and a prompt-to-update flow. Avoid skipWaiting without a prompt.
  • Apps with push, background sync or complex offline data. injectManifest from day one. The worker becomes real application code, with tests and code review. Offline-first architecture covers the data side.
  • Store distribution. Build a solid web PWA first, then add PWABuilder or Bubblewrap. Store packaging doesn't fix a weak PWA; reviewers reject thin wrappers.
  • Long-lived codebases on Workbox. Staying on Workbox 7 is fine. Plan a Serwist migration only when you need its features or framework support. Advanced Workbox has the migration checklist, including the cache and IndexedDB renames that make it more than a find-and-replace.

Legacy and unmaintained tools

Old tutorials still recommend tools you should not adopt in 2026:

  • sw-precache and sw-toolbox. Workbox's predecessors, deprecated since Workbox's release in 2017.
  • next-pwa (last published August 2022) and @ducanh2912/next-pwa (last published September 2024; its README recommends migrating to @serwist/next).
  • @nuxtjs/pwa (last published January 2021, for Nuxt 2). Use @vite-pwa/nuxt.
  • @pwabuilder/pwainstall (last published 2020). The maintained successor listed by PWABuilder is @khmyznikov/pwa-install.
  • Lighthouse "PWA" badges and scores. They no longer exist; don't gate CI on them.
  • workbox-sw from the Google CDN in new projects. It still works for classic workers, but a bundled worker avoids the third-party request and the lazy-loading pitfalls. See Workbox fundamentals.

Pages in this section

  • Workbox fundamentals


    Current version and maintenance status, the module map, generateSW vs injectManifest, the CLI, webpack and Node builds, routing, strategies, precaching and workbox-window, with complete configurations.

    Workbox fundamentals

  • Advanced Workbox


    Every plugin callback in order, custom Strategy subclasses, recipes, range requests, broadcast update, background sync queues, debugging, bundling and migrating to Serwist.

    Advanced Workbox

  • Vite PWA plugin


    vite-plugin-pwa in depth: strategies, registration modes, virtual modules, development mode, assets generation and framework packages.

    Vite PWA plugin

  • Framework integrations


    Next.js with Serwist, Angular's service worker, SvelteKit's built-in worker, Nuxt and Astro, with SSR and routing caveats.

    Framework integrations

  • PWABuilder


    Auditing a live PWA and generating Microsoft Store, Google Play and App Store packages, plus PWABuilder Studio and the starter template.

    PWABuilder

  • Testing and debugging


    DevTools workflows, automated service worker tests with Playwright, and auditing without Lighthouse's PWA category.

    Testing and debugging

Further reading

On this site

External references