FEB 15, 2026Mobile10 min read
Building Offline-First Mobile Apps with Expo
Mobile apps live in unreliable network environments. Here's how I build apps that work regardless of connectivity.
The Core Pattern
Every data operation goes through a local-first pipeline:
typescript
async function saveTransaction(tx: Transaction) {
await localDB.transactions.insert(tx);
await syncQueue.push({
type: 'CREATE',
table: 'transactions',
data: tx,
timestamp: Date.now()
});
if (navigator.onLine) {
syncManager.flush();
}
}"Users don't care about your server's uptime. They care that the app works when they open it."
Conflict Resolution
For my finance tracker Koin, I use timestamp-based last-write-wins. It's simple and works for 99% of cases. For the remaining 1%, I show a merge dialog.