Bharat Cab : Real-Time Ride-Hailing App

July 10, 2024

What Is This?

Bharat Cab is a full-stack, real-time ride-hailing application inspired by Uber/Ola. It connects passengers with nearby drivers in real time using WebSockets, interactive maps with live GPS tracking, OTP-based ride verification, and a distance-based pricing engine.

Tech Stack

Frontend: Remix.js v2, React 18, React Leaflet, OpenStreetMap, OSRM, Tailwind CSS, Socket.IO Client, TypeScript

Backend: Express.js, Socket.IO, PostgreSQL, Argon2, Cookie-based sessions, TypeScript

How It Works

Ride Flow

  1. User books a ride — picks source and destination on an interactive map, sees the price estimate, and requests a ride
  2. Broadcast to drivers — the server broadcasts the ride request to all online drivers via WebSocket
  3. Driver accepts — a modal pops up with ride details; first driver to accept locks the ride. A 4-digit PIN is generated for verification
  4. Live tracking — the driver's GPS streams to the server, which forwards it to the user's map in real time
  5. Automatic state transitions — the server computes Haversine distances continuously:
    • Driver < 1 km from pickup → rideNearby notification
    • Driver < 0.1 km from pickup → prompts OTP entry
    • Driver < 0.1 km from destination → triggers ride end
  6. OTP verification — passenger shares the PIN verbally; driver enters it to start the ride
  7. Review — after the ride ends, the user can rate and review

Distance-Based Pricing

The server calculates great-circle distance using the Haversine formula and maps it to a tiered price bracket (e.g., ≤5 km = ₹30, ≤10 km = ₹120, up to ≤500 km = ₹6000).

Architecture

The project is a monorepo with a clean layered backend:

routes  controllers  services  model  PostgreSQL
                  
               socket (Socket.IO)

Database Design

Five PostgreSQL tables — ACCOUNT (unified auth with user/driver roles), SESSION, USER, DRIVER (with status: offline/online/onride), and RIDE (with GPS coordinates stored as PostgreSQL POINT type, ride status lifecycle, PIN, price, and review).

Real-Time Engine

Socket.IO handles all real-time communication — driver registration, ride broadcasting, ride acceptance with lock mechanism, live GPS streaming, proximity-based notifications, OTP validation, and ride lifecycle events. In-memory socket registries map driver/user IDs to their active socket connections.

Map & Routing

React Leaflet renders the interactive map with custom markers for source, destination, and driver location. Route polylines are fetched from the free OSRM API, and reverse geocoding uses Nominatim — all open-source, zero cost. The map is scoped to the Bengaluru region.

Key Engineering Decisions

  • OTP-based ride verification prevents ride fraud — PIN generated server-side, shared verbally, validated via socket
  • Geographic automation — Haversine distance checks on every GPS update automatically trigger state transitions without user action
  • Singleton socket pattern — a single persistent WebSocket connection reused across the entire app via an IIFE-based singleton
  • Client-only map rendering — React Leaflet wrapped with ClientOnly from remix-utils to avoid SSR failures
  • Cookie-based auth with Argon2 hashing and session resolution middleware

What I Learned

This project gave me hands-on experience with real-time systems using WebSockets, GPS-based automation, and building a complete ride lifecycle from booking to review. Working with PostgreSQL's geospatial types, implementing the Haversine formula, and managing concurrent socket connections across multiple users and drivers deepened my understanding of building production-grade real-time applications.

View the source code →