Skip to content
Zowork
All case studies
Case study~8 min read

Offline-first: a clinical app that works with zero signal.

Home visits, rural clinics, basements with no bars. For a clinician in the field, the network is a luxury, not a guarantee. We built a mobile app for a US behavioral-health provider that lets them authenticate, document care and sign consent entirely offline, keeps every keystroke encrypted on the device, and syncs it back, intact and in order, the moment a signal returns.

Offline-firstMobile EngineeringEncryptionHIPAAOpen Source
offline · captured locally
encrypted · on device
Clinician device
encrypted store
Server
unreachable
3 notes pending
Introduction

Care doesn't wait for a signal

The hard part of an offline app isn’t the UI. It’s everything you take for granted when there’s a server in reach: who is this user, where does the data live, is it safe, and how do days of edits reconcile without corrupting a patient’s record.

The client, a US-based IT partner to health services providers, needed a documentation app that simply assumed there was no network and treated connectivity as a bonus. Below is how we answered each of those questions, and the two open-source libraries that came out of it.

The brief

An offline-first app, not an online one that tolerates drops

The distinction matters. We weren't hardening an online app against flaky Wi-Fi; we were building one where offline is the default path and the server is optional.

  • Authenticate and capture offline. An initial login that works with the device fully disconnected was non-negotiable.
  • Keep working through poor or no connectivity, with zero data loss while disconnected.
  • Sync on reconnect. Captured documents synchronise to the server the moment connectivity returns.
  • Search, filter and sort patient data in both online and offline modes.
  • Create progress notes and sign consent forms on-device, regardless of signal.
The challenge

Four problems that only exist offline

Each one is something an online app simply delegates to the server. Offline, there's no server to delegate to.

Offline authentication

With no server to verify against, the device itself must prove an authorized user, without leaving behind anything an attacker could steal.

On-device storage

Captured data needs somewhere durable to live, so the app can cold-start from exactly where the user left off.

Encryption at rest

HIPAA requires patient data on the device to be encrypted, ideally per user, with no secret sitting on disk.

Ordered sync

Days of edits must replay in the right order. Lose the ordering and you risk silently corrupting a record, the worst possible failure mode for clinical data.

Offline authentication + encryption

Proving who you are, with nothing to steal

The instant a user can open the app offline, the server is out of the loop, so something on the device has to establish that they’re authorized. The naive answer, caching a credential on the device, is exactly what has bitten mobile platforms historically: with the right tools, anything written to storage can be read back.

So we designed the app to store no secret at all. The user’s unlock code lives only in their head; entering it both proves who they are and unlocks their encrypted data in a single step. A wrong code yields nothing readable, and nothing saved on the device can reveal it.

Unlock code
never stored
Verified on device
no server needed
Data unlocked
per-user encryption
The principle
If there’s no secret on the device, there’s no secret to steal. One action gives two guarantees: the user is authenticated, and their data is unlocked, entirely offline.
Conflict-free sync

Syncing in order, without corruption

After days offline, a device holds a queue of changes: new notes, edits to those notes, signed forms. Replay them naively and things go wrong quietly: three edits to the same note race each other, or an update arrives before the record it belongs to even exists. For clinical data, a silently corrupted record is the worst possible failure.

So the sync engine is deliberately careful. Related changes are combined so they travel as one, duplicates are recognised and collapsed, and everything replays in the order it actually happened. The server always ends up with exactly what the clinician did, no more and no less.

ScenarioNaive replayOur sync engine
Three edits to one noteThree racing writes, last one winsOne clean, combined change
New record, then an editThe edit can arrive first and failOrder preserved, always
The same change queued twiceConflicting duplicatesRecognised and collapsed
Given back

Two gaps in the ecosystem, filled in public

Twice during the build we hit a gap where the open-source ecosystem had no good answer. Both times, we built the missing piece and gave it back.

redux-persist-sqlite-storage

A storage engine we released as a new open-source library, in production use by other teams ever since.

Core contribution to redux-offline

Our ordered, deduplicating sync improvements were contributed upstream, and we became core contributors to the library.

Why it matters
Open-source contributions are the strongest reference we can offer: the code is public, reviewed by strangers, and still in use. The client got a better app; the ecosystem got two better libraries.
Outcome

Shipped, and two libraries given back

2

Open-source libraries shipped or co-owned

given back to the ecosystem
100%

Of auth and capture works with zero connectivity

offline-first by design
0

Records lost or corrupted on sync

ordered, careful replay
  • An offline-first app with HIPAA-compliant, per-user encryption, and no secret ever stored on the device.
  • Clinicians authenticate, document and sign consent with no signal at all.
  • Every change syncs back intact and in order the moment connectivity returns.
Conclusion

Offline isn't an edge case in the field

For a clinician on a home visit, offline is the normal case. Building for it forces you to answer the questions online apps get to skip: identity, storage, encryption, reconciliation. Answer them well and the network becomes a detail. The app just works, and the data shows up safely the moment it can.

Have a workflow that has to keep working when the signal doesn’t? That’s exactly the kind of problem we like.

Talk to engineering