Associated with FuelBuddy

FuelBuddy India - Customer App (React Native Migration)

Migrated FuelBuddy's customer app from a PWA to React Native, hitting 100% feature parity across 14 user flows in 8 weeks.

FuelBuddy's customer app started as a Progressive Web App. That worked on Android, but on iOS it faced platform limitations: WebKit engine constraints, unreliable install-to-home-screen, limited storage, and missing push notification capabilities. For FuelBuddy, that meant the PWA could not reliably serve iOS users, and a native app was necessary to provide a stable mobile experience. I was part of the engineering team that rewrote the app in React Native.

What I worked on

  • PWA to React Native: Rewrote the app as a compiled React Native application, hitting 100% feature parity across 14 user flows in 8 weeks and ensuring a consistent native feel on both iOS and Android.
  • Working across the stack: Focused on the mobile frontend while building necessary CRUD APIs directly on Hasura GraphQL engine so feature development was never blocked on backend dependencies.
  • Shipping with the team: Collaborated closely with frontend engineers and product managers to translate requirements into tested features and keep production release cycles on schedule.

Why it mattered

Migrating to React Native established a reliable, single codebase across both iOS and Android. Shipping 14 user flows with full parity in 8 weeks allowed FuelBuddy to serve its entire mobile user base without maintaining separate platform implementations.

Team & Ownership

I was one of the engineers on this rewrite, working alongside frontend engineers and product managers to hit full parity across all 14 flows in the 8-week window the team set for the migration.

The GraphQL Layer

CRUD APIs run on Hasura, consumed through urql rather than Apollo, with GraphQL Codegen generating typed operations, 73 separate .graphql files covering the app's real surface area. Local state runs through Zustand, with MMKV as the fast key-value store backing it, and Zod validating data at the boundaries.

Location and Payments, Not Just CRUD

Delivery tracking pulls in react-native-maps, a dedicated geolocation service, and Turf.js for the actual geospatial math (distance, bounds, routing calculations), not just a marker on a map. Payment runs through two independent gateways: Easebuzz, integrated as a vendored local package rather than a registry dependency, and Axis Bank, whose API requires every request signed with AES-256-CBC (PBKDF2-derived key) and HMAC-SHA512, done in a hand-written native Android module (NdpsAESLibrary, bridged into JS via NativeModules) rather than a JS crypto library, since a payment gateway's signing requirement isn't something the RN layer can satisfy generically. Firebase covers both auth and analytics.

Reports, Not Just a Table

The reports flow renders delivery and business data as charts through Victory Native, then exports the same data to CSV: encoded with json2csv, written to disk through Android's Scoped Storage API (react-native-scoped-storage, required on Android 10+ once apps lost direct filesystem access), and handed off through the native share sheet.

Data Model & Scale

  • 13-14 distinct flow containers (address, assets, business, delivery, home, location, order, pickup, reports, settings, support, user, wallet) organize the app's navigation, consistent with the "14 user flows" figure.
  • A dedicated native Android module owns bank-grade request signing; everything else in the app stays in JS/TypeScript on top of React Native's bridge.

Stack

React Native, urql with GraphQL Code Generator, Zustand for state, MMKV for storage, Zod for validation, react-native-maps, Turf.js for geospatial calculations, Easebuzz and Axis Bank for payments (the latter behind a custom native AES/HMAC signing module), Victory Native for reporting charts, Firebase for auth and analytics, on Hasura GraphQL.