Context & Problem
Insurance field adjusters assess claims on-site — often at properties with poor or no cellular coverage — and need to record claim progress, photograph damage, and capture signatures without waiting for a connection. Generic tooling assumes connectivity and treats the phone as a thin client to a server. The client needed a purpose-built field app that treated offline as the default state rather than an error condition, and that could round-trip with their existing claims backend.
Adjusters capture claim reports, damage photos, and signatures in the field, where connectivity is unreliable, then need that data to reconcile with an established backend once back online. A connectivity-dependent client wasn't viable — work could not stall because a property had no signal. The app had to store everything locally, remain fully functional offline, and sync complete reports opportunistically, while conforming to the response shapes of a REST API the team did not control. It also carried an aging React Native baseline that blocked current native modules and lacked end-to-end type safety, so the work included a platform and language migration alongside the feature set.
Design Constraints
- platformThe app had to work fully offline on field devices — adjusters capture claims on-site where connectivity is unreliable.
- legacyIt had to integrate with an existing REST backend and conform to its established response shapes rather than redesign the API.
- platformA single React Native codebase had to ship to iOS, Android, and web.
Architecture Overview
Built a single React Native (Expo) codebase targeting iOS, Android, and web. Made the local database the source of truth: an expo-sqlite store modeled with Drizzle ORM, accessed exclusively through a repository layer so screens never touch storage directly, with migrations applied on startup. Structured API access as an Axios client with request/response interceptors and a typed endpoint registry, so local models map cleanly onto the backend's existing response shapes. Report capture combines camera photos, on-device digital signatures, and ZIP bundling so a finished report uploads as a single atomic, retriable payload. Authentication uses token-based sessions with secure credential storage, and the UI is an in-house component library and theme layer that replaced a third-party kit removed during the migration.
Key Engineering Decisions
Outcomes & Lessons Learned
Platforms
One React Native codebase targeting three platforms
Data Layer
A local SQLite + Drizzle store keeps the app fully usable with no connectivity
Platform Baseline
Migrated onto current React Native and React majors with full TypeScript strict mode
Retrospective
- Keeping a local SQLite schema in sync with an existing backend's response shape is the recurring tax of offline-first: every table mirrors the API's nullable fields, and a change on either side has to be threaded through hand-written Drizzle migrations or reads silently break.
- Replacing the third-party UI kit with an in-house component library removed an upgrade blocker during the React Native / React 19 migration, but the cost is ongoing — the team now owns accessibility and theming for every primitive the library used to provide.
