Why Logistics Apps Are Hard
Most mobile apps deal with data at rest. Logistics apps deal with data in motion — constantly changing, frequently conflicting, and always time-sensitive. A package that was in Lagos at 9am might be in Ibadan by noon and delayed by traffic at 2pm. Your app needs to reflect reality as it happens.
This creates engineering challenges that don't exist in typical CRUD apps: WebSocket connection management, location battery optimisation, offline-first data handling, and conflict resolution when the network drops mid-delivery.
The Three Apps You Actually Need
Most logistics platforms need three distinct applications, not one:
The driver app is the most demanding. Drivers are on the road, on low-powered phones, often with intermittent connectivity. It needs to work offline, sync aggressively when online, and minimise battery drain while still polling GPS frequently.
The dispatcher dashboard is a web application — a dense, real-time map view showing all active drivers, pending orders, and exception states. It needs WebSocket updates, map clustering, and filtering by zone, status, and driver.
The customer tracking page is the simplest but most visible. Customers want to see where their order is, right now. A shareable tracking link with live map embed is usually enough.
Location Tracking That Doesn't Kill Batteries
The naive approach — navigator.geolocation.watchPosition on full accuracy — drains a phone battery in 3–4 hours. That's not acceptable for a 10-hour driver shift.
The production approach uses adaptive location polling:
- High frequency (every 15s) when the driver is in transit with an active delivery
- Low frequency (every 2–3 min) when the driver is stationary or between orders
- Background location using Expo's expo-location with task manager, requesting Location.Accuracy.Balanced rather than Accuracy.High
Pair this with geofence triggers — instead of constant polling, fire events when a driver enters or exits a delivery zone. This is both battery-efficient and semantically meaningful.
Offline-First Architecture
Drivers will lose connectivity in tunnels, basements, and rural areas. Your app needs to handle this gracefully.
The pattern that works:
1. Optimistic local writes — driver marks delivery as complete in the app, which writes to a local SQLite store immediately
2. Background sync — a queue drains to the server when connectivity returns
3. Conflict resolution — if the server state has changed while offline, define clear merge rules (last-write-wins is usually fine for delivery status)
React Native with WatermelonDB or expo-sqlite provides this foundation. For the sync layer, a custom job queue with exponential backoff handles the edge cases.
Real-Time Map Updates
The dispatcher dashboard needs to update as drivers move. WebSockets are the right tool — long polling introduces too much latency.
Architecture:
- Driver app emits location updates via WebSocket (or REST with short polling as fallback)
- Server broadcasts to all subscribed dispatcher sessions
- Dashboard updates map markers in place without re-rendering the entire map
For React, react-map-gl (Mapbox) or Google Maps JS SDK handles the rendering. The key is updating marker positions imperatively rather than re-mounting components on each location change.
Proof of Delivery
A completed delivery with no evidence is a customer service nightmare. Build PoD from day one:
- Photo capture with automatic upload and compression
- Digital signature canvas
- Geolocation stamp tied to completion event
- Timestamp and driver ID attached to every PoD record
These aren't nice-to-haves — they're your first line of defence in every dispute.
The Stack I Use
For production logistics apps: React Native with Expo, WatermelonDB for local persistence, Socket.io for real-time, Google Maps Platform for mapping, PostgreSQL for the backend, and Redis for presence and pub/sub.
Building a logistics product? Let's discuss your requirements →