A regional utilities operator
A Flutter field app for 400 engineers working in basements, substations and rural sites with no usable signal.
- Engagement
- 20 weeks
- Year
- 2026
- Disciplines
- App Dev · Backend · UI/UX
- Jobs completed offline
- 61%
The problem
The client's 400 field engineers were carrying two devices: a rugged tablet running a decade-old job system that required connectivity, and their own phone for photographs, which were later emailed in and manually attached. Roughly six in ten jobs happened somewhere with no signal, so the tablet was effectively a viewer and the real record was paper.
What we did
- 01
Design offline-first, not offline-tolerant
The app has no loading state for job data because it never fetches it on demand. The engineer's assigned work for the next 72 hours is on the device before they leave the depot, and every action they take is written locally first. Connectivity is a background concern the interface never mentions.
- 02
Make conflict resolution a product decision
Two engineers editing the same asset record is a real scenario, not an edge case. Rather than last-write-wins, edits are stored as an append-only log per asset and merged on sync — and where two entries genuinely conflict, the app surfaces both to the supervisor rather than silently picking one.
- 03
Flutter, with the sync engine off the UI thread
One Dart codebase for both platforms, and the merge pass runs in a background isolate rather than on the UI thread — reconciling several hundred queued edits is real work, and doing it inline is what makes an app drop frames the moment signal returns. Camera and barcode go through platform channels to native implementations; those were the two places where a plugin cost enough in reliability to justify the extra code.
- 04
One rendering pipeline, one set of bugs
Flutter draws its own widgets rather than mapping to platform controls, so a layout that is correct on Android is correct on iOS. On a fleet of rugged tablets running four Android versions and a handful of iPads, that removed an entire category of per-device defect the previous vendor had been chasing.
What changed
Paper job sheets were retired nine months after rollout. The second device went with them: photographs are now captured in the job record with location and timestamp attached, which closed an audit finding the client had been carrying for three years.
- Jobs completed with no connectivity
- 61%
- Median sync time on reconnect
- 1.9s
- Devices carried per engineer
- 21
- Paper job sheets per month
- ~7,0000
- Platform-specific UI defects
- ~40 open0
Built with
- Flutter
- Dart
- Drift / SQLite
- Riverpod
- Go
- AWS
“The thing that convinced the crews was that it never showed them a spinner. It just worked in a basement, which is where half our work is.”