← All projects
Setu — offline-first community lifeline
JH26-X386Onepath · Rajshahi · RUET · 1 member · Crisis Tech
When the network dies, Setu keeps people findable — signed safe/help check-ins that sync phone-to-phone by QR, sound, or SMS, with no internet.
The problem
When Bangladesh went dark in July 2024, 130 million people kept their phones but lost each other. Families couldn't confirm who was safe, volunteers couldn't see where help was needed, and rumour replaced verified news. The Feni floods a month later repeated the same failure without politics: towers down, families unreachable. Nearly every tool we rely on assumes a working tower, a smartphone, and a data plan — in a crisis, most affected people have none of the three. Feature phones are still the majority of locally made handsets, so "download this app" excludes exactly the people who need help most.
The solution
Setu (সেতু, "bridge") is an offline-first PWA that stays useful at every level of infrastructure failure. Check-ins ("I am safe" / "need help"), missing-person reports, and official bulletins become small Ed25519-signed events stored on the device and merged conflict-free between devices — every phone is a courier.
The same packet travels over a ladder of transports: a WebSocket relay when there's internet; the same relay running on any volunteer's laptop when there's only local Wi-Fi; QR Beam when there's nothing — one phone plays fountain-coded animated QR frames, another scans them by camera, so two airplane-mode phones exchange dozens of check-ins in under a minute. Button phones join by SMS through a volunteer-run Android gateway ("SAFE Rahim Mirpur" appears on every board; "FIND Rahim" gets a reply), and a zero-JavaScript /lite page serves 2G-era browsers. Signed bulletins are verification-badged, so trusted information travels offline just like rumour — but provably distinct from it.
Stack: React + Vite PWA, IndexedDB, @noble/ed25519, CBOR, jsQR, Node.js + SQLite relay. Bangla/English, no accounts, built for cheap Androids.
Same honesty check as before — delete any line for a feature you didn't ship.
Tech stack
Frontend: React 18 + TypeScript, Vite, vite-plugin-pwa (Workbox) for offline caching, Tailwind CSS, Zustand. Storage: IndexedDB via Dexie. Crypto: @noble/ed25519 + @noble/hashes (event signing/verification). Encoding: cbor-x (compact event packets). QR: qrcode (generation), jsQR (camera decoding); fountain-coding (Luby transform) implemented in-project. Map: Leaflet + OpenStreetMap tiles (© OpenStreetMap contributors). Backend relay: Node.js 20, Hono, ws (WebSocket sync), better-sqlite3. SMS bridge: SMS Gateway for Android (capcom6, open source) running on a volunteer Android phone. Fonts: Noto Sans Bengali (SIL OFL, bundled locally). Hosting: [Fly.io / Render — whichever you used]. All dependencies are open source; full list with licenses in package.json and the README.
AI tools used (section 5 disclosure)
Claude (Anthropic) — planning, architecture design, and AI-assisted coding throughout the sprint; Claude Opus and Sonnet models via [Claude Code / the tool you used] for implementation, debugging, and tests. Google Gemini — occasional debugging cross-checks and idea comparison. All AI-generated code was reviewed, tested on real devices, and committed incrementally by me; project concept, decisions, and final integration are my own.
Two adjustments before pasting: swap in your actual hosting provider, and make the AI list match reality — name the exact tools/models you actually ran (e.g., drop Gemini if you never used it, use httpSMS instead of capcom6 if that's what you installed). Honest, specific disclosure costs you nothing here and judges respect it.