Native or cross-platform: deciding on evidence rather than preference
Both approaches build excellent products. The decision follows device capability requirements, team composition and roadmap shape.
Intermittent connectivity is harder to handle than no connectivity. Sync design decides whether the app is trusted in the field.
A device with no signal is easy to detect. A device on a connection that resolves DNS, opens a socket and then drops most packets is where naive implementations hang, retry and duplicate.
Design for the partial case explicitly: timeouts on every request, idempotent writes, and a queue that survives the app being killed mid-operation.
The application reads and writes locally and the interface never blocks on the network. Synchronisation is a background concern with visible status.
Last-write-wins silently discards work someone did, which in field applications destroys trust in the data. The person who spent twenty minutes on a record does not care about merge elegance.
Detect conflicts deterministically, preserve both versions with provenance, and present a clear choice with enough context. Most conflicts are rare enough that a human decision is affordable.
Test with a proxy that drops packets and adds latency, not with wifi switched off. Test the app being killed mid-sync, the device running out of storage, and a token expiring while queued work is pending.
These are the failure modes that produce support tickets, and they are all reproducible if you decide to reproduce them.
Field users trust an application when they can tell what it has done with their work. Ambiguity about whether something was saved is the fastest route to people keeping a paper backup, which defeats the purpose.
Show explicit, honest state: saved locally, queued to send, sent, and failed with a reason. Distinguish between waiting for a connection and having failed permanently, because the user's response differs.
Where something cannot be completed offline, say so at the point the user attempts it rather than accepting the input and failing later. Clear refusal is better than false acceptance.
SQLite through a platform wrapper is the dependable default. Purpose-built sync engines can save time when their model matches yours; check how they handle conflicts before committing.
Meaningfully to the affected features, and more to testing. It is also almost entirely front-loaded retrofitting later changes the data layer and everything above it.
No. Classify each operation as safe offline, safe with reservation, or requiring connectivity. Blocking some operations clearly is better than a conflict flow nobody understands.
Keep reading
Both approaches build excellent products. The decision follows device capability requirements, team composition and roadmap shape.
Users judge an app in the first few seconds. Startup time, scroll smoothness and battery drain are what they actually notice.
Store listings are a search and conversion problem. Most of the available improvement is in the first screenful.