A real-time emergency response platform: a live incident map, GPS-based responder tracking over WebSockets, tiered resource/hospital discovery, a metadata-based fake-report filter, and a disaster relief request workflow — built entirely on free, keyless infrastructure (OpenStreetMap, Overpass, OSRM).
Originally conceived at the IITM NIRMAAN cohort (selected from 200+ startups) as a 5-person team project; this repo is the engineering build-out of that concept. Full product spec: REACH - Report.pdf.
This is a local development project, not deployed — clone and run it to see it work (see Running Locally).
Everything below is live, working code — not a mockup — unless explicitly marked otherwise.
| Feature | How it works |
|---|---|
| Live map, real GPS | navigator.geolocation.watchPosition centers the map on your real location and live-updates a "you are here" marker as you move. |
| Hospital search | Queries the free Overpass API for real amenity=hospital nodes/ways near you, racing 3 public mirrors in parallel (Promise.any) since individual mirrors are unreliable — falls back to a short-lived cache on failure. |
| Live responder tracking | A standalone Socket.IO server computes a real driving route via OSRM between a responder and an incident, decodes the polyline, and streams interpolated position + bearing updates over WebSockets in real time (with turn-based speed variation). |
| Fake-report / media verification | /submit — uploads a photo, extracts real EXIF GPS + timestamp via exifr, computes haversine distance to the claimed incident location, and accepts/flags it per a 3 km-tolerance, fail-open policy (missing/unreadable metadata is accepted rather than blocking a genuine report). |
| Disaster Alerts mode | Toggles the map to a dark CartoDB theme, shows a color-coded severity banner, and a relief request form that posts to a real API route and returns an assigned volunteer + ETA. |
| Resource tiering | Hospitals/equipment render with tiered marker icons (H1–H3 / M1–M3 / F1–F3, exported from the team's Figma design). Hospital tiers are simulated (OSM carries no readiness data); equipment points are simulated inventory. |
| Guidelines | Static first-aid reference (CPR, bleeding, shock, burns, crime-related first aid). |
| Profile | Medical record editor persisted to localStorage, certifications, activity history. |
| Event Response Dashboard | Per-incident modal: details/status, media, voice-channel + transcript UI, and the live tracking map tab. |
Being upfront about this matters more than pretending otherwise:
- Incident data (the 3 demo alerts — cardiac event, structure fire, robbery) is seeded mock data, not a real 911/dispatch feed. Their coordinates are relocated relative to your real GPS fix on each load so they're visible wherever you are, rather than fixed to the original St. Louis demo location.
- Voice channels / AI call transcription in the Event Modal are UI mockups — no real WebRTC or ASR wired up.
- Auth is a demo flow using
localStorage, not a real user system. - Weather/disaster feed in Disaster Mode is a static simulated banner, not a live weather API.
- Hospital Enquiry / Twilio dispatch calling described in the product report is not implemented.
flowchart TB
subgraph Client["Next.js App (localhost:3000)"]
Map["Leaflet Map<br/>(react-leaflet + OSM tiles)"]
GPS["Browser Geolocation<br/>watchPosition"]
Dash["Event Dashboard / Modal"]
Submit["Media Submission"]
end
subgraph API["Next.js API Routes"]
Alerts["/api/alerts<br/>mock incidents, relocated to user"]
Search["/api/search-category<br/>Overpass hospital search"]
Random["/api/random<br/>simulated equipment"]
Verify["/api/verify-media<br/>EXIF GPS validation"]
Relief["/api/disaster-requests"]
end
subgraph Server["Socket.IO Server (localhost:5000)"]
Track["Live responder simulation<br/>OSRM route + position stream"]
end
subgraph Free["Free External Services"]
Overpass["Overpass API<br/>(3 mirrors, raced in parallel)"]
OSRM["OSRM public router"]
Tiles["OSM / CartoDB tiles"]
end
GPS --> Map
Map --> API
Dash <--> Track
Submit --> Verify
Search --> Overpass
Track --> OSRM
Map --> Tiles
- Frontend: Next.js 15 (App Router), React 19, Tailwind CSS,
react-leaflet/ Leaflet - Realtime backend: Node.js, Express, Socket.IO (
server/) - Mapping/geo, all free & keyless: OpenStreetMap tiles, Overpass API (place search), OSRM (routing),
@mapbox/polyline - Media verification:
exifr(real EXIF parsing) - Design: marker icon set generated in Figma and pulled in via the Figma MCP plugin
Requires Node.js 18+. No API keys or billing needed — everything runs on free public services.
# 1. Install and run the Next.js app
npm install
npm run dev # http://localhost:3000
# 2. In a second terminal, install and run the live-tracking server
cd server
npm install
npm run dev # http://localhost:5000Open http://localhost:3000, allow location access, and the map centers on you. Note: the Overpass hospital lookup depends on free public infrastructure and can occasionally take up to ~15s (or fail over between mirrors) under load — that's an inherent limitation of the free tier, not a bug.
Responders can record a spoken report from the incident modal's Communications
tab. The clip is captured with MediaRecorder, posted to /api/transcribe, and
forwarded to reach-asr (CyberRik/reach-asr)
— a Whisper checkpoint LoRA fine-tuned for telephony-band noisy audio — and the
transcript is appended to the incident feed.
# .env
ASR_SERVICE_URL=http://localhost:8081Without it the mic still works and the recording is attached; only the
transcript is missing. That is deliberate: the audio is the report and the
transcript is an enrichment, so an inference outage must never be the reason
someone's emergency recording disappears. GET /api/transcribe proxies the
service's health check so the UI can say so up front rather than after a
responder has already recorded twenty seconds.
The model lives in a separate process because it is a resident ~290MB PyTorch graph that holds a GPU for the process lifetime, which is the opposite shape from a route handler that scales to zero between requests. Keeping the boundary means this app deploys unchanged while the model sits on whatever has the GPU.
app/ Next.js App Router pages + API routes
api/ alerts, random, search-category, disaster-requests, verify-media, transcribe
guidelines/ profile/ submit/ login/ register/
components/ Map, Marker, EventNavigation (dashboard/modal/live tracking), VoiceReport, forms
server/ Standalone Socket.IO server for live responder-tracking simulation
public/markers/ Figma-exported marker icon set
MIT — see LICENSE.
Originally built by the R.E.A.C.H. team (M. Rahul, Ritankar Mondal, Manyam Srivallabh, Soumika Male, Suggu Prem Kumar) for the IITM NIRMAAN Summer 2025 Cohort.