by @cap-go
Guide to building offline-first Capacitor apps with data synchronization, caching strategies, and conflict resolution. Covers SQLite, service workers, and network detection. Use this skill when users need their app to work without internet.
Build apps that work seamlessly with or without internet connectivity.
┌─────────────────────────────────────────┐
│ UI Layer │
├─────────────────────────────────────────┤
│ Service Layer │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Online Mode │ │ Offline Mode │ │
│ └──────┬──────┘ └────────┬────────┘ │
├─────────┼──────────────────┼────────────┤
│ │ Sync Manager │ │
│ └────────┬─────────┘ │
├──────────────────┼──────────────────────┤
│ ┌───────────────┴───────────────────┐ │
│ │ Local Database │ │
│ │ (SQLite / IndexedDB) │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
bun add @capacitor/network
bunx cap sync
import { Network } from '@capacitor/network';
// Check current status
const status = await Network.getStatus();
console.log('Connected:', status.connected);
console.log('Connection type:', status.connectionType);
// Listen for changes
Network.addListener('networkStatusChange', (status) => {
console.log('Network status changed:', status.connected);
if (status.connected) {
// Back online - sync data
syncManager.syncPendingChanges();
} else {
// Offline - show indicator
showOfflineIndicator();
}
});
import { Network } from '@capacitor/network';
class NetworkAwareService {
private isOnline = true;
constructor() {
this.init();
}
private async init() {
const status = await Network.getStatus();
this.isOnline = status.connected;
Network.addListener('networ...