FlexRide Mobile
FlexRide Mobile is a true native iOS client for the same FlexRide car rental platform — built incrementally with Expo Router, Native Tabs, and NativeWind, sharing the exact same MongoDB Atlas database and business logic as the web rebuild rather than a separate, disconnected app. Every real-data feature was ported faithfully from the web app's actual source rather than re-derived: the same 182-vehicle fleet, the same date-range availability check with guest-vs-account-holder conflict rules, and the same 24-hour soft-reservation hold mechanic (tracked on-device with AsyncStorage, mirroring the web app's localStorage layer). Data fetching runs through TanStack Query with a shared cache across screens, backed by real Expo Router API routes hitting the database directly.
- Client
- Personal Project
- Role
- Solo Full-Stack Developer
- Duration
- Ongoing solo build
- Year
- 2026

Stack
Key Features
The Impact
vehicles, same live fleet as the web app
The Challenge
Mobile-native UI conventions and a phone screen are a different design problem than the web app's layouts, but the underlying product — real inventory, real availability, real reservations — had to stay identical. The challenge was building a genuinely native experience (native tab bar, native gestures, on-device storage) without drifting from the web app's actual data model or re-implementing business logic that could silently diverge from it.
The Architecture
Expo Router (file-based routing, Native Tabs for the root tab bar) with a Stack layered on top so detail screens push correctly over the tab bar — a common Expo Router gap when combining Tabs with non-tab routes. Data fetching is TanStack Query end to end, including the reservation-creation mutation. The reservation flow POSTs to a real Expo API route that re-verifies availability server-side (never trusting the client-side check alone), running the same overlap-detection query as the web app's Reservation model. Guest holds persist locally via AsyncStorage, structured to match the web app's guest-reservation shape exactly so the two clients could share a linking flow once mobile auth exists.
The Solution
Built in incremental, verified phases rather than one large build: navigation shell and mock data first, then real database wiring, then a full audit pass removing every piece of placeholder/fixture content that had crept in from the initial design pass (a fake signed-in user, a permanently-shown fake guest-hold banner, fabricated ratings on cars with no real reviews, a discount silently pre-applied at checkout with no real referral system behind it). Each phase was verified live against the actual database — including deliberately reproducing a real booking conflict to confirm the availability check genuinely blocks a double-reservation, not just in the happy path.


The Results
Real end-to-end reservation flow verified against live data: date selection → server-side availability check → reservation creation → an on-device 24-hour guest hold with a live countdown, all backed by the same database as the web app
Found and removed a real pricing bug during an honesty audit: a referral discount was silently pre-applied to every checkout with no referral system behind it
Ported the web app's exact guest-vs-account-holder booking conflict rules into a new Expo API route rather than approximating the logic
Fixed a routing gap where Expo Router's Tabs+TabSlot pattern silently swallowed navigation to non-tab screens (car details, category pages) — confirmed via direct URL navigation, not just UI clicks
Full car comparison feature (up to 3 vehicles, side-by-side specs) ported from the web app's implementation, adapted to native sheet and scroll patterns
