The idea crosses several layers at once: mobile UI, native radio access, routing, local storage and message security. A short prototype needed to make that architecture tangible and show what remained unresolved.
My part
My work covers the app monorepo and native modules. The landing page was generated in Lovable.
What this shows
I can explore an unfamiliar technical problem quickly, split it into workable boundaries and distinguish a prototype from a deployable system.
Where it started
Mesh was a one-day hackathon prototype. It explored an Expo interface, a shared relay protocol and native Bluetooth and Wi-Fi modules for nearby messaging.
See it in action
Product walkthrough · 0:41 · 60 FPS · English narration
English AI narration · Subtitles included · Play with sound, or read the transcript.
Read the video transcript
0:00 Mesh is a hackathon prototype exploring messaging when ordinary networks fail.
0:08 Nearby phones relay messages for each other, rather than relying on one central connection.
0:15 A hop limit keeps messages from circulating forever.
0:21 Native Android and iOS modules connect the shared app to each platform's radios.
0:30 Local storage keeps contacts, messages, routes and peers together on the device.
The decisions behind the product
Separate the shared protocol from the device
I organized the app, web client and shared routing core in a monorepo, with native Kotlin and Swift modules for the device-specific radio work.
Define how messages move
The core models relay routes, loop prevention and a hop limit. Local SQLite storage holds identity, contacts, messages, peers and the queue.
Keep the prototype boundary visible
The crypto interface was designed, but the mobile implementation remained a placeholder. The web gateway server and final app integration were not completed.
What came out of the work
A concrete architecture in one day
Seventeen app commits landed on a single calendar day, covering five workspaces and the shared relay model.
A clearly bounded experiment
The result is an archived prototype, not a secure emergency messenger. It shows the system design and implementation direction without claiming field reliability.
1 dayto assemble the hackathon prototype24 Jan 2026 · calendar time, not working hours
2native platforms explored: Android and iOSPrototype · incomplete app integration
Inside the implementation
Explore the features, architecture and quality checks
What I built
A Turborepo monorepo on Bun with five workspaces: the Expo mobile app, a web client (PWA), a shared TypeScript core, and native Android and iOS modules
Native radio code: Kotlin services for Bluetooth LE and Wi-Fi Direct on Android and a Swift CoreBluetooth service on iOS, each with a React Native bridge
A relay protocol in the shared core: a hop limit of 10, a route list that stops loops, and routing that prefers a direct peer, then the fewest hops
On-device storage in SQLite: 10 tables for the identity, contacts, conversations, messages, routes, peers, groups and a message queue
A crypto interface designed around X25519, XChaCha20-Poly1305 and Ed25519; the mobile implementation remained a simplified placeholder and is not secure
A web client with a gateway connection service; the gateway server itself was not built
EAS Build profiles: a development client, an internal preview APK and auto-incremented store builds
A landing page generated in Lovable, hosted on Vercel, with cookieless Umami analytics
How it works
DiscoverPhones find each other over Bluetooth LE, and over Wi-Fi Direct on Android.
RelayEach phone passes the message on, adds itself to the route and lowers the hop limit by one.
DeliverA direct message stops at the phone it is addressed to. Routing prefers a direct peer, then the fewest hops.
Quality and reliability
Strict TypeScript across the monorepo, with Turborepo tasks for build, typecheck and lint
Protocol rules live in one shared core package, used by both the mobile app and the web client
Known limit: a one-day prototype with no automated tests; the encryption is a placeholder and the native modules are not declared as dependencies of the app