Offline-first is a data model decision, not a caching one
Bolting a cache onto an online-first app produces something that fails in more interesting ways. Offline changes what your data model has to be.
"Add offline support" is one of those requests that sounds like a feature and is actually an architecture.
Teams usually reach for a cache. The app tries the network, falls back to cached data, and shows a stale banner. This works until a user writes something offline, and then you discover that your entire data model assumed the server was the only thing that assigns identity.
Identity has to be local
If your client cannot mint an ID, it cannot create a record offline. Server-assigned auto-increment IDs are the single most common blocker we find.
The fix is client-generated UUIDs. The client creates records with real identity immediately; the server accepts them as-is. Suddenly a queued create is just a record that has not synced yet, rather than a special pending state that needs its own code path.
Every write is a queued intent
Once identity is local, every mutation becomes an entry in an outbox: an intent, with a timestamp, that will eventually reach the server.
This is more code than a cache. It is also the only version that survives a technician spending six hours in a basement.
Decide conflict policy before you need it
Most conflicts are not real. Two edits to different fields of the same record can usually both be applied. Field-level merge handles the majority.
For genuine conflicts — two people editing the same field — pick a rule and be explicit. On Northwind, the rule was that the technician on site wins, because they are looking at the equipment and the supervisor is not. Supervisors see a flag and can override.
What matters is that the rule is written down and visible in the UI. Silent conflict resolution is how you lose users' trust permanently.
Test on the worst device
We test on the cheapest Android in the client's fleet, on airplane mode, with a full local database. Not the newest iPhone on office wifi.
Almost every offline bug we have shipped would have been caught by that one habit.