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-buildfor any Vite-based stack. Its sibling packages cover Nuxt, SvelteKit and Astro. - Some frameworks ship their own service worker story: Angular's
@angular/service-workerand SvelteKit's built-insrc/service-workersupport. 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.generateSWwrites the whole worker from configuration.injectManifestreplacesself.__WB_MANIFESTin a worker you wrote. The CLI adds an interactiveworkbox wizard. Workbox fundamentals covers every option.vite-plugin-pwa. Wrapsworkbox-build's two modes (strategies: "generateSW" | "injectManifest") and adds what Vite users need: manifest generation and injection, a virtual registration module (virtual:pwa-registerplus React, Vue, Svelte, Solid and Preact variants) withpromptorautoUpdatebehavior, 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-pluginand@serwist/viteall implementinjectManifestwith theself.__SW_MANIFESTinjection point. Framework packages such as@serwist/nexthide 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-generatoris 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 asminimal2023Preset. It usessharp(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 manifesticons.pwa-asset-generatorrenders its sources in headless Chrome throughpuppeteer-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 yourmanifest.jsonandindex.htmlwith 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-startertemplate, 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.webmanifestgenerates an Android project from your manifest, andbubblewrap buildproduces a signed APK and App Bundle. You still have to publish/.well-known/assetlinks.jsonwith 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 generateSWwith 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
navigateFallbackwith a strict denylist, and a prompt-to-update flow. AvoidskipWaitingwithout a prompt. - Apps with push, background sync or complex offline data.
injectManifestfrom 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-precacheandsw-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-swfrom 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,
generateSWvsinjectManifest, the CLI, webpack and Node builds, routing, strategies, precaching andworkbox-window, with complete configurations. -
Advanced Workbox
Every plugin callback in order, custom
Strategysubclasses, recipes, range requests, broadcast update, background sync queues, debugging, bundling and migrating to Serwist. -
Vite PWA plugin
vite-plugin-pwa in depth: strategies, registration modes, virtual modules, development mode, assets generation and framework packages.
-
Framework integrations
Next.js with Serwist, Angular's service worker, SvelteKit's built-in worker, Nuxt and Astro, with SSR and routing caveats.
-
PWABuilder
Auditing a live PWA and generating Microsoft Store, Google Play and App Store packages, plus PWABuilder Studio and the starter template.
-
Testing and debugging
DevTools workflows, automated service worker tests with Playwright, and auditing without Lighthouse's PWA category.
Further reading¶
On this site
- Workbox fundamentals
- Advanced Workbox
- Vite PWA plugin
- Framework integrations
- PWABuilder
- Precaching and runtime caching
- Trusted Web Activity
- Production checklist
External references
- Workbox documentation
- Serwist documentation
- Vite PWA documentation
- PWABuilder documentation
- Opening a Microsoft Store developer account (Microsoft Learn)
- Bubblewrap on GitHub
- pwa-asset-generator on GitHub
- Angular service workers guide
- SvelteKit service workers
- Next.js PWA guide
- Playwright: service workers