An offline-first mobile app for field operations

Case study. Data capture that keeps working with no signal, and syncs itself when one returns. Client details withheld for confidentiality.

At a glance

  • Client: a business whose crews work in remote locations, often without mobile coverage
  • What they needed: to replace paper forms with an app that works offline, and give the office a live view of what comes in
  • Platforms: iOS and Android from one codebase, plus a web dashboard for the office
  • Result: 60% faster data entry, near-zero sync errors
  • My role: solo developer, end-to-end delivery

The brief

Crews were filling in paper forms in the field and the office typed them up afterwards. Every handover added delay, every retype added errors, and nobody in the office knew what had happened on site until days later. An ordinary app would not have fixed it: much of the work happens where there is no signal at all.

So the app had to be offline-first. Not "works with a weak connection", but works with none: capture everything on the device, keep it safe, and upload it later without anyone having to think about it.

See it in action

A live illustration with sample data. The names, figures and addresses are invented, and these are not the client's screens.

Field admin Live mapRecordsFormsCrews Today Export Northern 12 Northern 9 Eastern 3 Southern 5 · flagged DepotDepot check B A C D +− siteflaggedcrew (live position) Crews in the field Crew A · Eastern 3synced 10:40 · 4 records Crew B · Northern 12offline · 3 pending on devicesynced just now · 3 records Crew C · Southern 51 reading flagged for review Crew D · Depotsynced 10:47 · 2 records Crew E · Depotsynced 10:12 · 1 record Crew Fnot started today Message all crews Submissions today · by hour128 so far · 9 still on devices131 so far · 6 still on devices 7am10am1pm4pm 9:41 No signal · 3 records waiting Back in coverage · uploading Sync Inspection · Northern 123 photos · 10:51 QueuedSynced Inspection · Northern 95 photos · 09:30 QueuedSynced Safety check · Depotno photos · 08:40 QueuedSynced Delivery note · Depot1 photo · 08:05Synced Everything is in3 records · 8 photos · 0 errors Records stay on the device until theserver confirms every one of them. Crew B has been out of coverage all morning. The app kept working. The moment a signal returns, three records and eight photos upload on their own, and each one pops onto the office map as the server confirms it. Nobody taps anything. Offline-first: the phone is the source of truth until the server has every record. The crew's phone, back in coverage 9:41 No signal · 3 records waiting Back in coverage · uploading Sync Inspection · Northern 123 photos · 10:51 QueuedSynced Inspection · Northern 95 photos · 09:30 QueuedSynced Safety check · Depotno photos · 08:40 QueuedSynced Delivery note · Depot1 photo · 08:05Synced Everything is in3 records · 8 photos · 0 errors Records stay on the device until theserver confirms every one of them. The office map, as each record lands Field admin Live mapRecordsFormsCrews Today Export Northern 12 Northern 9 Eastern 3 Southern 5 · flagged DepotDepot check B A C D +− siteflaggedcrew (live position) Crews in the field Crew A · Eastern 3synced 10:40 · 4 records Crew B · Northern 12offline · 3 pending on devicesynced just now · 3 records Crew C · Southern 51 reading flagged for review Crew D · Depotsynced 10:47 · 2 records Crew E · Depotsynced 10:12 · 1 record Crew Fnot started today Message all crews Submissions today · by hour128 so far · 9 still on devices131 so far · 6 still on devices 7am10am1pm4pm Field admin Live mapRecordsFormsCrews Today Export Northern 12 Northern 9 Eastern 3 Southern 5 · flagged DepotDepot check B A C D +− siteflaggedcrew (live position) Crews in the field Crew A · Eastern 3synced 10:40 · 4 records Crew B · Northern 12offline · 3 pending on devicesynced just now · 3 records Crew C · Southern 51 reading flagged for review Crew D · Depotsynced 10:47 · 2 records Crew E · Depotsynced 10:12 · 1 record Crew Fnot started today Message all crews Submissions today · by hour128 so far · 9 still on devices131 so far · 6 still on devices 7am10am1pm4pm
Live: a crew comes back into coverage. Queued records upload one after another, and each one appears on the office map as it lands. Sample data.

What I built

Offline-first capture

Forms save to the device instantly, with or without a connection. Crews never wait on a spinner and never lose a record.

Sync that looks after itself

Queued records upload when a signal returns, photos included, and are only cleared from the device once the server confirms them.

Form builder

The office defines and changes forms (fields, choices, units, required values) and publishes them to the crews without an app update.

Office dashboard

Records as they arrive, counts per crew, readings outside expected ranges flagged for review, and export to Excel.

Backend API

A small API on Cloudflare Workers in front of a Supabase database, handling uploads, validation and access for both the app and the dashboard.

One codebase, two platforms

Built in Flutter, so iOS and Android ship from the same code and every fix lands on both at once.

Technology

FlutteriOS & AndroidSupabaseCloudflare Workers

Outcome

Data entry became 60% faster, because it happens once, on site, instead of twice. Sync errors fell to near zero, because records are never retyped and never dropped. The office sees the day's work as it happens rather than days later.

Need something similar?

Offline-first apps are a speciality. If your people work where the signal doesn't, get in touch.