November 12, 2025 · 8 min read
An automotive service startup came to us needing two very different apps in one: a polished booking experience for customers, and a rugged field-operations tool for technicians working in basements and garages where connectivity is often the first thing to fail. Building both natively twice wasn't in the budget or the timeline, so the architecture had to make cross-platform genuinely work for both audiences.
We used Flutter with a shared core package for authentication, API contracts and design tokens, but split the customer and technician experiences into separate app targets built from that shared core. This meant the technician app could ship a stripped-down, low-bandwidth-friendly UI without dragging along customer-facing assets it never needed, while both stayed visually and behaviourally consistent.
The harder engineering problem wasn't the customer app — it was making job updates reliable when a technician's phone lost signal mid-service. We built an offline-first sync layer that queues status updates, photos and parts-used logs locally and reconciles them against the server the moment connectivity returns, with conflict resolution that always favours the most recent field update over stale server state.
On the customer side, every extra screen between opening the app and confirming a booking measurably hurt conversion during testing. We collapsed vehicle selection, service package and scheduling into a single guided flow with sensible defaults pre-filled from the customer's service history, cutting the average booking flow from six screens to three.
The app drove a 300% increase in service bookings within three months of launch, and technician-reported sync failures — the metric we cared about most internally — stayed under 1% even in low-connectivity basements and underground parking structures.
Free 30-minute discovery call. No sales pitch — just an honest conversation about your project and how we can help.