A comprehensive Progressive Web App template with enhanced auto-updater and cache management features. This template addresses common PWA deployment issues like browser caching and ensures installed PWAs update properly when deployed to platforms like GitHub Pages.
- Automatic Update Detection: Checks for new versions every 30 minutes
- Smart Cache Management: Intelligent caching strategies with expiration
- Force Update Capability: Manual cache clearing and app refresh
- Update Notifications: User-friendly update prompts with changelog
- Version Control: Automatic version tracking and management
- Offline Support: Works without internet connection
- Installable: Can be installed on mobile and desktop
- Responsive Design: Works on all device sizes
- Encrypted Storage: Secure local data storage with encryption
- Push Notifications: Support for push notifications (when configured)
- Cache Management UI: Visual cache information and controls
- Deployment Script: Automated version management for deployments
- Debug Information: Detailed logging and status reporting
- Cross-Platform: Works on all modern browsers
- Clone or download this template
- Serve locally using a web server (required for service worker)
- Install the PWA using your browser's install prompt
- Deploy to your hosting platform
# Using Python 3
python -m http.server 8000
# Using Node.js (if you have http-server installed)
npx http-server
# Using PHP
php -S localhost:8000Then visit http://localhost:8000 in your browser.
Use the included deployment script to automatically manage versions:
# Auto-increment patch version
node deploy.js
# Set specific version
node deploy.js 4.1.0
# Increment minor version
node deploy.js --minor
# Increment major version
node deploy.js --major- Update the version in
version.json - Update the cache name in
service-worker.js - Deploy to your hosting platform
- The PWA will automatically update for users
The cache behavior can be configured in service-worker.js:
const CACHE_CONFIG = {
name: 'pwa-template-v4',
version: '4.0.0',
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
maxEntries: 100, // Maximum cached entries
// ... more options
};Update checking frequency and notifications can be configured:
const UPDATE_CONFIG = {
checkInterval: 30 * 60 * 1000, // 30 minutes
notificationTitle: 'PWA Template Update',
// ... more options
};- Old Issue: Browsers cache PWA files, preventing updates
- Solution: Version-based cache names and automatic cache invalidation
- Old Issue: Installed PWAs continue using old cached versions
- Solution: Service worker detects updates and prompts users
- Old Issue: Users need to manually clear browser cache
- Solution: Automatic cache management with user controls
- Old Issue: Users don't know when updates are available
- Solution: In-app update notifications with changelog
PWA-Template/
├── index.html # Main app page
├── app.js # Main application logic
├── service-worker.js # Enhanced service worker with auto-updater
├── version.json # Version information for updates
├── manifest.json # PWA manifest
├── styles.css # App styles
├── encrypted-storage.js # Encrypted storage utilities
├── deploy.js # Deployment script
├── icons/ # App icons
│ ├── icon-192x192.png
│ ├── icon-512x512.png
│ └── icon.svg
└── README.md # This file
- Developer deploys new version using
deploy.js - Service worker detects new version via
version.json - App notifies user of available update
- User clicks update or app auto-updates
- Cache is cleared and new version loads
- App continues with fresh content
- Expiration: Cached files expire after 7 days
- Size Limits: Maximum 100 cached entries
- Cleanup: Automatic removal of old caches
- Background Updates: Fresh content fetched in background
- Clear All Caches: Remove all cached files
- Force Update: Clear cache and reload app
- Cache Information: View cache statistics
- Update Check: Manually check for updates
- ✅ Chrome/Edge (Chromium-based)
- ✅ Firefox
- ✅ Safari (iOS 11.3+)
- ✅ Samsung Internet
⚠️ Internet Explorer (Limited support)
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with vanilla HTML, CSS, and JavaScript
- Uses modern web APIs for PWA functionality
- Inspired by the need for better PWA update management
A minimal, production-ready Progressive Web App template with encrypted storage and offline support.
- Offline Support: Service worker for caching and offline functionality
- Encrypted Storage: AES-256-GCM encryption with browser fallbacks
- Mobile Ready: Responsive design for all devices
- Installable: Native app experience
- Fast Loading: Optimized caching strategies
- Data Management: Save, load, export, import, and inspect data
- Clean UI: Minimal, modern interface
- Zero Dependencies: Pure HTML, CSS, and JavaScript
PWA Template/
├── index.html # Main HTML file (minimal structure)
├── styles.css # Clean, minimal CSS styles
├── app.js # Core PWA functionality
├── encrypted-storage.js # AES-256 encryption utilities
├── service-worker.js # Offline caching
├── manifest.json # PWA configuration
├── icons/ # App icons
│ ├── icon-192x192.png
│ ├── icon-512x512.png
│ └── *.svg
├── LICENSE # The Unlicense
├── .gitignore # Git ignore patterns
└── README.md # Documentation
-
Clone this repository:
git clone <repository-url> cd pwa-template
-
Start a local server:
# Using Python python -m http.server 8000 # Using Node.js npx serve . # Using PHP php -S localhost:8000
-
Open in browser: Navigate to
http://localhost:8000 -
Test PWA features:
- Install the app (install prompt should appear)
- Toggle offline mode to test caching
- Use the storage demo to save/load encrypted data
- Test on mobile devices for full experience
The template includes a robust encrypted storage system with AES-256-GCM encryption:
// Initialize storage
const storage = new EncryptedStorage();
// Save encrypted data
const myData = { message: 'Hello, secure world!', timestamp: Date.now() };
await storage.saveEncrypted('my-note', myData);
// Load encrypted data
const loadedData = await storage.loadEncrypted('my-note');
console.log(loadedData); // { message: 'Hello, secure world!', timestamp: 1234567890 }// Save with password
const sensitiveData = {
accountNumber: '1234-5678-9012',
apiKey: 'secret-api-key-here'
};
await storage.saveEncrypted('sensitive-data', sensitiveData, 'myPassword123');
// Load with password (required)
const decrypted = await storage.loadEncrypted('sensitive-data', 'myPassword123');// Use localStorage (default)
const localStorage = new EncryptedStorage({ backend: 'localStorage' });
// Use IndexedDB for larger data
const indexedStorage = new EncryptedStorage({ backend: 'indexedDB' });
// Memory storage (session only)
const memoryStorage = new EncryptedStorage({ backend: 'memory' });// Custom configuration
const storage = new EncryptedStorage({
keyName: 'my-app-key', // Custom key storage name
backend: 'indexedDB', // Storage backend
keySize: 256 // AES key size (256-bit)
});
// Encrypt/decrypt without storage
const encrypted = await storage.encrypt('sensitive text', 'password');
const decrypted = await storage.decrypt(encrypted, 'password');
// Clean up all encrypted data
await storage.clearAll();try {
await storage.saveEncrypted('data-key', myData);
console.log('Data saved successfully');
} catch (error) {
console.error('Failed to save data:', error.message);
// Handle encryption failure, storage quota exceeded, etc.
}
try {
const data = await storage.loadEncrypted('data-key', 'wrongPassword');
} catch (error) {
console.error('Failed to decrypt:', error.message);
// Handle wrong password, corrupted data, etc.
}The storage system automatically detects and adapts to browser capabilities:
- Modern browsers: Uses Web Crypto API with AES-256-GCM
- Older browsers: Falls back to XOR encryption
- Storage: Prefers localStorage, falls back to IndexedDB, then memory
- Encoding: Uses TextEncoder/Decoder with fallbacks
The built-in demo showcases:
- Save: Store text or JSON with optional password encryption
- Load: Retrieve saved data (password required for encrypted items)
- Export: Download backup file (preserves encryption)
- Import: Restore from backup files
- Inspect: View storage details and browser access instructions
- Clear: Remove all stored data with confirmation
const storage = new EncryptedStorage({
keyName: 'pwa-encryption-key', // Key storage identifier
backend: 'localStorage', // 'localStorage' | 'indexedDB' | 'memory'
keySize: 256 // AES key size: 128, 192, or 256 bits
});| Method | Description | Parameters | Returns |
|---|---|---|---|
saveEncrypted(key, data, password?) |
Save encrypted data | key: string, data: any, password: string? |
Promise<boolean> |
loadEncrypted(key, password?) |
Load and decrypt data | key: string, password: string? |
Promise<any | null> |
encrypt(data, password?) |
Encrypt data without saving | data: any, password: string? |
Promise<string> |
decrypt(encryptedData, password?) |
Decrypt data | encryptedData: string, password: string? |
Promise<any> |
clearAll() |
Remove all encrypted data | none | Promise<boolean> |
| Method | Description | Returns |
|---|---|---|
generateAndStoreKey(password?) |
Generate new encryption key | Promise<Array<number>> |
isWebCryptoAvailable() |
Check Web Crypto API support | boolean |
isLocalStorageAvailable() |
Check localStorage support | boolean |
isIndexedDBAvailable() |
Check IndexedDB support | boolean |
// Check what features are available
console.log(storage.features);
// {
// webCrypto: true, // Web Crypto API available
// localStorage: true, // localStorage available
// indexedDB: true, // IndexedDB available
// textEncoder: true // TextEncoder available
// }
// Check encryption method being used
console.log(storage.encryptionMethod); // 'webcrypto' or 'simple'✅ HTTPS: Required for production (localhost works for development)
✅ Web App Manifest: manifest.json with proper configuration
✅ Service Worker: Handles caching and offline functionality
✅ Icons: Multiple sizes for different platforms
✅ Responsive Design: Works on all screen sizes
✅ Fast Loading: Service worker caching strategy
- App Name: Update
manifest.jsonandindex.htmltitle - Colors: Modify gradient colors in
styles.css - Icons: Replace files in
icons/directory - Cache: Update file list in
service-worker.js
manifest.json: App metadata and configurationstyles.css: Colors, fonts, and layoutindex.html: App structure and meta tagsservice-worker.js: Caching strategy and file list
- ✅ Chrome/Chromium (full support)
- ✅ Firefox (full support)
- ✅ Safari (full support)
- ✅ Edge (full support)
⚠️ Internet Explorer (limited support)
- Deploy to HTTPS (required for PWA features)
- Test offline functionality
- Verify installation works on target devices
- Run Lighthouse audit for PWA compliance
- Update cache version in service worker when deploying changes
- DevTools: Use Application tab to debug PWA features
- Offline Testing: Toggle network in DevTools
- PWA Audit: Run Lighthouse for compliance check
- Installation: Test on mobile devices for full experience
- Cache Updates: Increment
CACHE_NAMEwhen updating files
This project is released into the public domain under The Unlicense. You are free to use, modify, distribute, or sell this software for any purpose without restriction.