Why offline-first is not optional in our markets
If your product assumes a stable connection, it will fail exactly when people need it. Designing for intermittent networks changes the architecture, not just the UI.
A lot of software is built and tested on office broadband, then shipped to people on a congested mobile network. The result is an interface that spins forever and loses what the user typed.
Connection loss is normal, not exceptional
Treating a dropped request as an error state is the root mistake. For a delivery driver in a basement or a teacher in a rural school, losing connection is the ordinary case. The product should absorb it rather than complain about it.
Make every write idempotent
Once you accept that requests will be retried, you have to make retries safe. Every operation that changes data needs a client-generated key so the server can recognise a duplicate and return the original result rather than performing the action twice.
This one decision eliminates an entire category of bug: the double charge, the duplicate order, the attendance record entered twice.
Decide what happens on conflict, in advance
If two people edit the same record offline, somebody has to win. Last-write-wins is fine for a draft and unacceptable for a balance. Choosing this per data type, early, avoids discovering it in production.
Budget the page, not just the feature
Offline tolerance is wasted if the first load never completes. We set a page-weight budget at the start and enforce it in CI, because performance that is not measured on every merge quietly decays.
Keep reading
How much does an app cost in 2026?
There is no single number, but there is a method. Here is how we turn a rough idea into a range you can plan around, and what makes that range move.
Native or cross-platform: how we actually choose
We default to Flutter for cross-platform work and go native when the project earns it. The decision comes from constraints, not fashion.