Spin
Revolutionizing urban micro-mobility
Live Demo
Overview
Spin is Ford Mobility's shared micro-mobility platform — electric scooters and bikes operating across 100+ cities in North America and Europe, serving more than 1M riders. I spent three years on the production iOS and Android apps shipping React Native features across the full ride lifecycle: discovery, rental, in-ride state, payments, and trip history. Work spanned cross-platform React Native, native modules in Swift and Kotlin for location and Bluetooth, and the CI pipeline that got it all to the stores.
The Challenge
Shared mobility apps live and die by latency. A rider staring at a blank map walks to a competitor's scooter. The legacy app had GPS accuracy problems, a battery-draining location loop, a 3% crash rate eating retention, and a feature pipeline that couldn't ship fast across two platforms and a dozen city operations.
The Solution
Rebuilt the hot paths as native modules (location, BLE, maps) exposed to React Native, so the UI stayed cross-platform without giving up native performance. Tuned location polling per rider state, added predictive map tile and scooter caching so first-paint felt instant, and gated every rider-facing release behind feature flags with staged rollouts across cities.
Architecture
A cross-platform React Native app with native modules for the latency-sensitive paths, backed by a typed state layer and an offline-tolerant data flow. A flaky cell signal should never interrupt a ride.
Key Decisions & Tradeoffs
React Native + native modules, not fully native
Why: Shared ~85% of code across iOS and Android while keeping native code for the paths that actually need it (location, BLE, maps). The alternative — two separate native codebases — meant every rider feature shipped twice.
Adaptive location polling tied to rider state
Why: Battery drain was killing retention. A fixed-cadence GPS loop is wasteful; tuning polling to state (idle vs. riding vs. searching) dropped polling cost dramatically without hurting accuracy where it mattered.
Predictive map tile and scooter caching
Why: First-paint of the map was the single biggest drop-off point. Caching the last view + pre-fetching adjacent tiles made the map feel instant even on cold starts, which directly moved conversion.
Feature flags end-to-end, staged rollouts per city
Why: Multi-city operations meant a bad release could strand riders in a city I'd never visited. Every rider-facing change shipped behind a flag with per-city staged rollouts and instant kill switches.
Crash-first observability
Why: A 3% crash rate is a hidden tax on retention you don't notice in dashboards. Crashlytics triage built into the sprint cadence, with SLOs on crash-free sessions, drove the rate to sub-1% and lifted retention alongside it.
What I took away from this project
Lessons that still shape how I build — in my own words.
Perceived performance lives in the first 300ms
Map first-paint was the single biggest drop-off point in the funnel. No rider waits for a blank map — they walk to a competitor's scooter. We threw caching, tile pre-fetch, and adaptive location polling at it until cold start felt instant, and that alone moved conversion more than any visual refresh ever did. I've used the same playbook on every app since: optimize the first 300ms like nothing else matters.
Battery drain is a silent retention killer
A fixed-cadence GPS loop looks fine in a one-day test and disastrous over a month. I didn't take this seriously until I watched weekly-active riders drop off in a cohort that had nothing to do with product quality — they were just turning location off. Tuning polling to rider state (idle vs. riding vs. searching) clawed back retention we didn't know we were losing.
Feature flags are how small teams ship safely across many cities
Shipping to 100+ city operations without flags would have meant that every release was a coordination call. Per-city staged rollouts plus kill switches meant I could ship aggressively and roll back a bad release for a single market in minutes. It changed my relationship with 'risky' changes permanently.
Impact
Technology Stack
Frontend
Maps & Location
Native
CI & Testing
Key Features
Want something like this, built for you?
If the Spin story sounds close to what you're trying to ship, a 30-min call is the fastest way to find out if we're a fit.