@angular/pwa and @angular/service-worker are Angular-specific packages that simplify adding Progressive Web App (PWA) capabilities and service worker functionality to Angular applications. sw-precache and sw-toolbox were early Google-authored libraries for generating and managing service workers but are now deprecated. workbox-sw is part of the modern Workbox suite, a robust and flexible set of libraries for implementing service workers with advanced caching strategies, background sync, and more — suitable for any framework or vanilla JavaScript projects.
When building Progressive Web Apps (PWAs), choosing the right service worker tooling is critical for reliability, performance, and maintainability. The landscape includes Angular-specific solutions (@angular/pwa, @angular/service-worker), legacy Google libraries (sw-precache, sw-toolbox), and the modern standard (workbox-sw). Let’s break down how they differ in practice.
@angular/pwa is a convenience package for Angular CLI projects. It adds a web app manifest and enables @angular/service-worker with sensible defaults. It’s actively maintained as part of the Angular ecosystem.
@angular/service-worker provides Angular’s built-in service worker implementation. It uses a JSON-based configuration and integrates with Angular’s build pipeline to generate a service worker that caches assets and API responses. Actively maintained.
sw-precache and sw-toolbox are deprecated. Both were published by Google but are no longer updated. Their npm pages explicitly recommend migrating to Workbox. Do not use them in new projects.
workbox-sw is the entry point to the Workbox library suite. It’s actively developed, widely adopted, and offers modular, composable APIs for every aspect of service worker logic. It works with any framework or no framework at all.
⚠️ Important:
sw-precacheandsw-toolboxshould be avoided entirely. Official documentation states they are obsolete and replaced by Workbox.
@angular/pwa sets up everything with one command:
ng add @angular/pwa
This creates manifest.webmanifest, adds icons, and configures @angular/service-worker. No code changes needed.
@angular/service-worker requires manual activation in app.module.ts:
// app.module.ts
import { ServiceWorkerModule } from '@angular/service-worker';
@NgModule({
imports: [
// ...
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production
})
]
})
export class AppModule { }
And a ngsw-config.json defines what to cache:
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html"]
}
}]
}
With workbox-sw, you write your own service worker file (e.g., sw.js) and import Workbox modules:
// sw.js
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
// Precache files generated by your build tool
precacheAndRoute(self.__WB_MANIFEST);
// Cache API responses with a network-first strategy
registerRoute(
({ url }) => url.pathname.startsWith('/api/'),
new NetworkFirst()
);
You then register it in your main app:
// main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
For historical context, here’s how they worked:
sw-precache (build-time):
// In a build script
const swPrecache = require('sw-precache');
swPrecache.write('service-worker.js', {
staticFileGlobs: ['dist/**/*.{js,html,css}']
});
sw-toolbox (runtime):
// In service-worker.js
importScripts('sw-toolbox.js');
toolbox.router.get('/api/*', toolbox.networkFirst);
Again — these are deprecated. Avoid them.
Uses a declarative model. You define “asset groups” (for static files) and “data groups” (for dynamic requests) in ngsw-config.json:
{
"dataGroups": [{
"name": "api-data",
"urls": ["/api/**"],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 100,
"maxAge": "1h"
}
}]
}
"freshness" = network-first"performance" = cache-firstLimited to these two strategies. No custom logic allowed.
Offers full programmatic control with multiple strategies:
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
import { registerRoute } from 'workbox-routing';
// Cache-first for images
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst()
);
// Stale-while-revalidate for fonts
registerRoute(
({ url }) => url.pathname.endsWith('.woff2'),
new StaleWhileRevalidate()
);
You can also create custom strategies or combine plugins (e.g., cache expiration, broadcast updates).
sw-toolbox offered similar strategies but with a simpler API:
// Deprecated — do not use
toolbox.router.get('/images/*', toolbox.cacheFirst);
toolbox.router.get('/api/*', toolbox.networkFirst);
But lacked plugins, debugging, and modern features like background sync.
Angular service worker logs to ngsw/state (a special debug URL) and uses versioned caching with safe updates. However, debugging cache misses or custom behaviors is hard due to the black-box nature of the generated worker.
Workbox provides excellent dev tools:
workbox-cli for generating and injecting manifestsworkbox-windowExample enabling debug logs:
// In development
workbox.setConfig({ debug: true });
@angular/pwa and @angular/service-worker: Angular only. They rely on Angular CLI’s build process and won’t work in React, Vue, or vanilla apps.workbox-sw: Framework-agnostic. Used by developers across all ecosystems.sw-precache/sw-toolbox: Were framework-agnostic but are obsolete.@angular/pwa for simple PWAs.@angular/service-worker directly if you need to customize caching.sw-precache or sw-toolbox.Many Angular teams migrate from @angular/service-worker to Workbox when they need more control. This involves:
@angular/service-workersw.js with Workboxangular.json to include the service worker in builds| Package | Status | Framework | Caching Control | Custom Logic | Recommended? |
|---|---|---|---|---|---|
@angular/pwa | Active | Angular | Low (defaults) | ❌ | ✅ (Angular only) |
@angular/service-worker | Active | Angular | Medium (JSON) | ❌ | ✅ (Angular only) |
sw-precache | Deprecated | Any | Low | ❌ | ❌ |
sw-toolbox | Deprecated | Any | Medium | Limited | ❌ |
workbox-sw | Active | Any | High | ✅ | ✅ (All projects) |
For most professional teams, Workbox is the right choice unless you’re fully committed to Angular’s opinionated PWA model and don’t need advanced features. The deprecated libraries have no place in new codebases — their replacements in Workbox are more powerful, better documented, and actively supported. Choose based on your need for control versus convenience, and always prefer maintained, community-backed tools for production-critical infrastructure like service workers.
Choose @angular/pwa if you're building an Angular application and want a quick, opinionated way to add PWA features like a manifest file and a basic service worker setup. It installs both the manifest and configures @angular/service-worker automatically, making it ideal for getting started with minimal configuration in Angular CLI projects.
Choose @angular/service-worker when you need fine-grained control over caching behavior in an Angular app beyond what @angular/pwa provides out of the box. It integrates tightly with Angular’s build system and uses a declarative ngsw-config.json to define asset and data groups, but is only suitable for Angular projects and lacks the flexibility of general-purpose tools like Workbox.
Do not use sw-precache in new projects — it is officially deprecated and no longer maintained. It was designed to generate a service worker at build time that precached static assets, but has been superseded by Workbox’s workbox-precaching module, which offers better performance, debugging, and compatibility.
Avoid sw-toolbox for new development — it is deprecated and unmaintained. It provided runtime caching strategies (like cache-first or network-first) via a simple API, but its functionality is now fully covered (and improved upon) by Workbox’s workbox-strategies and workbox-routing modules.
Choose workbox-sw (or the broader Workbox ecosystem) when you need a powerful, framework-agnostic, and actively maintained solution for service workers. It supports advanced caching strategies, background sync, offline analytics, and developer-friendly debugging. While it requires more setup than Angular’s built-in tools, it gives you full control and is the industry standard for production-grade PWAs outside Angular or when Angular’s service worker is too restrictive.
@angular/pwaThis is a schematic for adding Progressive Web App support to an Angular project. Run the schematic with the Angular CLI:
ng add @angular/pwa --project <project-name>
Executing the command mentioned above will perform the following actions:
@angular/service-worker as a dependency to your project.index.html file to inlclude a link to add the manifest.webmanifest file.ngsw-config.json, specifying caching behaviors and other settings.See Getting started with service workers for more information.