Open-source, offline-first emergency coordination platform.
Connect victims with resources through a privacy-preserving, decentralized PWA.
Quick Start · How It Works · Architecture · Structure · Contributing · Docs
OpenRelief is a Progressive Web App for decentralized emergency coordination. It connects victims with resources via a privacy-preserving interface, addressing scaling bottlenecks through database-native spatial filtering and mitigating alarm fatigue through intelligent consensus and trust algorithms.
Why? During disasters, centralized systems fail and networks drop out. OpenRelief is built to keep working when it matters most — offline-first, trust-weighted, and geographically aware.
| Feature | What it does |
|---|---|
| 🔴 Emergency Reporting | One-tap reporting with type, severity, and automatic geolocation |
| 🗺️ Live Map | MapLibre GL map with real-time incident markers and resource overlays |
| 📴 Offline-First PWA | Service Worker caches the app; reports queue and sync when back online |
| 🤝 Trust & Reputation | Weighted trust scores resist Sybil attacks and false reporting |
| 🗳️ Consensus Engine | Cross-confirms incidents from multiple sources to cut alarm fatigue |
| 📍 Geofenced Dispatch | PostGIS spatial queries route alerts to nearby responders in <100ms |
| 🔔 Push Notifications | Web Push (VAPID) with iOS background-silent delivery |
| 🔒 Privacy-First | Row-Level Security, data export, and GDPR-aligned controls |
- Node.js 18+ (Node 20 LTS recommended)
- npm 8+
- Supabase CLI (for local database):
npm install -g supabase - Docker (required by
supabase startfor local Postgres + PostGIS)
# 1. Clone the repository
git clone https://github.com/openrelief/openrelief.git
cd openrelief
# 2. Install dependencies
npm install
# 3. Start local Supabase (PostgreSQL + PostGIS + Auth)
supabase start
# 4. Configure environment variables
cp .env.example .env.local
# → Fill in the Supabase URL + keys from `supabase status`
# 5. Run the development server
npm run devOpen http://localhost:3000 and you're live. 🎉
🖥️ Watch the terminal launch in action
To regenerate this GIF locally:
bash scripts/make-launch-gif.sh(requiresffmpeg).
| Command | Description |
|---|---|
npm run dev |
Start Next.js dev server |
npm run build |
Production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run type-check |
TypeScript type check (tsc --noEmit) |
npm test |
Run Jest unit/integration tests |
npm run test:e2e:playwright |
Run Playwright E2E tests |
npm run test:coverage |
Coverage report |
npm run db:migrate |
Push Supabase migrations |
npm run db:seed |
Seed local database |
npm run format |
Format with Prettier |
See AGENTS.md for the full command reference.
- Report — A victim (or bystander) opens the PWA and taps "Report", selecting an emergency type. Their geolocation is attached automatically. This works offline: the report queues in the Service Worker.
- Validate — When connectivity returns, the request hits the edge (Next.js middleware / Cloudflare Workers). Rate limiting, input validation, and the reporter's trust score gate the submission to resist Sybil attacks.
- Geo-dispatch — Supabase PostGIS runs a spatial proximity query to find responders and resources near the incident — typically under 100ms.
- Consensus — The consensus engine cross-checks whether other reports describe the same incident, raising confidence and suppressing duplicate alarms (mitigating alarm fatigue).
- Respond — Verified alerts push to nearby responders via Web Push and appear instantly on the live map through Supabase Realtime.
OpenRelief is a three-tier system:
- ① Client (PWA) — Next.js 15 App Router + React 18 + Zustand. A Service
Worker provides offline caching and background sync. TanStack Query handles
server state; Zustand manages local/realtime state (
emergencyStore,trustStore,locationStore,offlineStore). - ② Edge — Next.js middleware plus optional Cloudflare Workers enforce security headers, Redis-backed rate limiting, input validation, Supabase auth sessions, Web Push delivery, and Sentry monitoring.
- ③ Data (Supabase) — PostgreSQL 15 with PostGIS powers spatial queries and geofencing. Row-Level Security (RLS) governs data access. The Trust Engine scores reporter reputation; the Consensus Engine corroborates incidents. Supabase Realtime streams live map updates.
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router), React 18 |
| Language | TypeScript (strict mode) |
| Database / Auth | Supabase (PostgreSQL, PostGIS, Auth, RLS, Realtime) |
| State | Zustand (persist + subscribeWithSelector) |
| Data Fetching | TanStack Query v5 |
| Styling | Tailwind CSS + CVA + Radix UI |
| Maps | MapLibre GL JS |
| Spatial | Turf.js + geolib |
| Edge Functions | Cloudflare Workers |
| Monitoring | Sentry (client/server/edge) |
| Rate Limiting | Upstash Redis |
| Validation | Zod + custom validators |
openrelief/
├── src/
│ ├── app/ # Next.js App Router (pages + API routes)
│ ├── components/ # UI, map, trust, emergency, providers...
│ ├── hooks/ # Custom React hooks (queries, mutations)
│ ├── store/ # Zustand state stores
│ ├── lib/ # Supabase client, security, monitoring, utils
│ ├── edge/ # Cloudflare Workers
│ ├── types/ # TypeScript definitions
│ └── middleware.ts # Security, rate limiting, validation
├── supabase/ # Migrations, config, seed data
├── public/ # Static assets, PWA icons, service worker
├── docs/ # Comprehensive documentation
├── tests/ # Test suites
├── scripts/ # Build/test/utility scripts
└── .github/ # CI workflows, PR template, code owners
npm test # All Jest unit/integration tests
npm run test:coverage # Coverage report
npm run test:e2e:playwright # E2E tests (Playwright)
npm run test:lighthouse # Lighthouse CI performance auditThe project targets >80% coverage on critical components and <100ms
alert dispatch latency. See docs/testing/ for details.
Copy .env.example to .env.local and fill in your keys. Required for
the app to boot:
| Variable | Required | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
✅ | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
✅ | Supabase anonymous (public) key |
SUPABASE_SERVICE_ROLE_KEY |
✅ | Server-side service role key |
Optional variables (Redis, Sentry, VAPID push, MapTiler, etc.) are documented
in .env.example. Run supabase status to find your local
keys during development.
Contributions are welcome! This is an open-source project built by the community.
- Fork the repository and create a branch from
main - Install deps:
npm install - Develop — run
npm run dev,npm run lint,npm run type-check - Test — add/Update tests; ensure
npm testpasses - Commit — pre-commit hooks (Husky + lint-staged) auto-format your code
- Open a PR — describe your changes using the PR template
Read the full Contributing Guide and Code of Conduct.
🎯 Priority contribution areas
- Frontend/PWA — Service Worker optimization, MapLibre performance, offline sync
- Database — PostGIS spatial query tuning, RLS policies, triggers
- Security/Privacy — Trust algorithm, Sybil prevention, GDPR tooling
- DevOps — CI/CD, edge function deployment, monitoring
- Mobile — iOS background processing, push delivery
The full documentation index lives at docs/index.md. Quick links:
- Architecture — as-built overview, diagrams, data model, trust & consensus
- API reference — endpoints, auth, realtime
- Database schema — full DDL, RLS, functions
- Deployment — Vercel + Supabase + Cloudflare
- Security · Privacy
- Getting started · Contributing
- Issues: Report bugs or request features
- Discussions: Ask questions
- Good first issues: Start here
- Foundation — Repository, Next.js PWA, MapLibre, DB schema
- Trust System — Trust scores, consensus engine, Sybil resistance
- Alert Optimization — PostGIS tuning, edge functions, iOS background
- Resilience — Offline mesh networking, LoRaWAN integration
OpenRelief is licensed under the MIT License.
Built with ❤️ for resilient communities. Every contribution helps save lives during emergencies.
↑ Back to top


