Progressive Web App patterns with Workbox 7.x, service worker lifecycle, offline-first strategies, and installability. Use when building PWAs, service workers, or offline support.
View on GitHubyonatangross/orchestkit
ork-frontend-advanced
January 25, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/orchestkit/blob/main/plugins/ork-frontend-advanced/skills/pwa-patterns/SKILL.md -a claude-code --skill pwa-patternsInstallation paths:
.claude/skills/pwa-patterns/# PWA Patterns
Progressive Web App patterns using Workbox 7.x for service worker management, offline-first strategies, and app-like experiences.
## Service Worker Lifecycle
```
Installing -> Waiting -> Active
│ │ │
install activated fetch events
(precache) when old SW (runtime cache)
is gone
```
## Workbox: Generate Service Worker
```javascript
// build-sw.js (Node.js)
const { generateSW } = require('workbox-build');
async function buildServiceWorker() {
await generateSW({
globDirectory: 'dist/',
globPatterns: ['**/*.{html,js,css,png,jpg,json,woff2}'],
swDest: 'dist/sw.js',
clientsClaim: true,
skipWaiting: true,
navigateFallback: '/index.html',
navigateFallbackDenylist: [/^\/api\//],
runtimeCaching: [
{
urlPattern: /^https:\/\/api\.example\.com\//,
handler: 'NetworkFirst',
options: { cacheName: 'api-cache', networkTimeoutSeconds: 10 },
},
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/,
handler: 'CacheFirst',
options: { cacheName: 'images', expiration: { maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 } },
},
],
});
}
```
## Caching Strategies
```javascript
// CacheFirst: Static assets that rarely change
registerRoute(/\.(?:js|css|woff2)$/, new CacheFirst({
cacheName: 'static-v1',
plugins: [new ExpirationPlugin({ maxEntries: 100, maxAgeSeconds: 365 * 24 * 60 * 60 })],
}));
// NetworkFirst: API calls (fresh data preferred)
registerRoute(/\/api\//, new NetworkFirst({
cacheName: 'api-cache',
networkTimeoutSeconds: 10,
plugins: [new CacheableResponsePlugin({ statuses: [0, 200] })],
}));
// StaleWhileRevalidate: User avatars, non-critical images
registerRoute(/\/avatars\//, new StaleWhileRevalidate({ cacheName: 'avatars' }));
// NetworkOnly: Auth endpoints
registerRoute(/\/auth\//, new NetworkOnly());
```
## VitePWA Integration
```typescript
// vite.config.ts
import { VitePWA } from 'vit