Offline-first apps for field teams

Field staff lose signal in basements, rural roads and hospital corridors. Offline-first apps treat that as normal. Here is how to design storage, sync, conflicts and privacy.

What offline-first apps do differently

Most web apps assume a network and treat its absence as an error. Offline-first apps reverse that assumption. They save every action to storage on the device first, show the result immediately, and sync with the server when a connection is available. The user never waits on the network to finish their work.

For field teams, that difference is the whole product. Inspectors, outreach workers, clinical staff and crews often work where signal drops out: inside large buildings, in rural areas, or during storms. An app that freezes or loses an entry in those moments teaches people to go back to paper.

The building blocks in a web app

You do not need a native app to work offline. Modern browsers provide the pieces.

  • Service workers sit between the app, the browser and the network. MDN describes them as a kind of proxy that can serve the app from cache when the network is unavailable. They only run in secure contexts, meaning HTTPS.
  • IndexedDB is a transactional database in the browser for structured data, including files. Its operations are asynchronous, and data is isolated per origin.
  • The Storage API lets an app request persistent storage with navigator.storage.persist(). Without it, data is stored on a best-effort basis and can be evicted under storage pressure.
  • The Web Crypto API, through SubtleCrypto, can encrypt data on the device in secure contexts.

Plan for storage limits and eviction

Browser storage is not a vault. According to MDN, best-effort data can be removed when the device runs low on space, and when a browser evicts an origin it deletes all of that origin's data at once. Safari, with cross-site tracking prevention on, also deletes script-created data for sites without user interaction in the last seven days of browser use.

Design with that in mind. Request persistent storage. Sync as soon as a connection exists, so the device holds unsynced work for as short a time as possible. Show users clearly how many entries are waiting to sync, so nobody clears their browser with a day of work still on the device.

Version your local database schema from day one. When an app update changes the shape of stored data, the app must migrate records that are still waiting to sync, without losing any of them. This is one of the easiest offline bugs to ship and one of the most painful to recover from.

Sync: queue every change

The simplest reliable pattern is an outbox. Each change is written to a local queue with a unique ID generated on the device, a timestamp, and the user who made it. When the app is online, it sends the queue in order and removes each item only after the server confirms it.

  • Make every server write idempotent, keyed on the client-generated ID, so a retried request never creates a duplicate.
  • Retry on reconnect, on app open, and on a timer. The Background Synchronization API can help, but MDN marks it as limited availability and not supported in some widely used browsers, so never rely on it alone.
  • Pull changes from the server in small batches since the last successful sync, not the full dataset every time.
  • Record sync results so support can see what happened when someone reports a missing entry.

Conflicts: decide the rules before you write code

A conflict happens when two people change the same record while at least one is offline. There is no universal fix, only rules that fit your data. Choose them per record type during design.

  • Append-only records, such as visit logs, counts and notes, rarely conflict. Model data as new entries instead of edits wherever you can.
  • Last write wins is acceptable for low-stakes fields, but compare timestamps from the server, not device clocks, which drift.
  • Field-level merging keeps both changes when two people edit different fields of the same record.
  • Some conflicts need a person. Flag them, keep both versions, and show a simple screen to resolve them.
  • Conflict-free replicated data types (CRDTs) can merge concurrent edits automatically, but they add complexity that most field apps do not need.

Design the interface for spotty signal

Offline-first is as much a design problem as a technical one. Users need to trust that their work is safe, and trust comes from clear, honest feedback.

  • Show a small, always-visible sync status: online or offline, and how many changes are waiting.
  • Never block an action on a network spinner. Save locally, confirm immediately, and sync in the background.
  • Mark records that have not synced yet, so a supervisor looking at the server knows the data may be incomplete.
  • When sync fails, say what failed and what will happen next, in plain words, instead of a generic error.
  • Cache the reference data users need, such as forms, picklists and site lists, before they head out.

Web app or native app?

A web app with a service worker can be installed to the home screen, updates without app store review, and runs on any device with a modern browser. That makes it a strong default for internal field tools. A native app makes more sense when you need deep access to device hardware, heavy background processing, or very large local files. Decide based on what the field work requires, not habit.

Privacy by design for devices that leave the building

A field device can be lost, shared or stolen. The safest data is data you never collect. Before designing screens, ask what the app truly needs to store. When we built an offline-first workload tracker for a healthcare team, the requirement was counts and times only, with no patient identifiers. That single decision removed most of the privacy risk before a line of code was written.

  • Collect the minimum. Every field you add is a field you must protect.
  • Keep only unsynced and recently needed data on the device, and clear it after confirmed sync.
  • Encrypt sensitive local data and require sign-in or a passcode to open the app.
  • Use short sessions on shared devices, and give administrators a way to revoke access.
  • Log access and changes on the server, where the logs cannot be erased with the device.

Test offline like you mean it

Browser developer tools can simulate offline mode, but real conditions are messier: connections that drop halfway through a request, very slow networks, devices that sleep. Test full workdays offline, then reconnect and verify every entry arrived exactly once. Test on the cheapest device your team actually carries, not the newest phone in the office, and test with the browser your staff really use. Then send the app out with a small group for a week of real work before a full rollout, and read the sync logs every day. Foundry Peak builds offline-first apps for field teams in business, healthcare and public-sector settings, with privacy decisions made at the start.

Sources

Common questions

What is an offline-first app?

An offline-first app saves every action to storage on the device first, shows the result immediately, and syncs with the server when a connection is available. Users can keep working with no signal. In a web app this is usually built with a service worker for the app shell and IndexedDB for data.

How do offline apps handle sync conflicts?

They apply rules chosen for each type of record. Append-only data rarely conflicts. Low-stakes fields can use last write wins with server timestamps. Field-level merging keeps edits to different fields. Conflicts that need judgment are flagged so a person can choose between the saved versions.

Can browser storage be deleted in an offline web app?

Yes. By default, browsers store data on a best-effort basis and can evict it under storage pressure. Safari can also delete script-created data for sites without user interaction in seven days. Request persistent storage with navigator.storage.persist() and sync often to keep unsynced work on the device briefly.

Tell us what you're building.

We reply within one business day. If we're not the right fit, we'll say so and point you somewhere better.