Skip to main content
Jonathan Andrei
Back to all posts
Jan. 2026 - Feb. 20266 min read

50 Screens, 25 Tables, One Solo Developer, One Month

Building a real social platform for the RevenueCat Shipyard hackathon meant treating it like a startup, not a demo. Swipe-based discovery, real-time chat, convergence detection, RevenueCat-gated features, all behind Supabase Row Level Security.

React NativeSupabaseRLSRevenueCatHackathon
Roamly logo on a soft gradient background.
Roamly: a social discovery app shaped around the way digital nomads actually move between cities.

Hackathon-grade apps usually die in the second week of use because the demo path is the only path the developer ever exercised. With Roamly I wanted to see how close to production-shaped a solo build could get in a single contest cycle.

Why I built it

Existing social apps assume you live somewhere. Nomads don't. The interesting question for someone moving every few weeks isn't 'who is near me right now', it's 'who is also heading to Lisbon in October, and can I trust them before I get there'. Nothing on the market answered that cleanly, so I built it.

What ended up on the table

  • 50+ React Native screens covering swipe-based discovery, real-time chat, group features, voice prompts, and a community-vouched verification system.
  • A modular service layer of 15+ services and a Supabase backend with 25+ tables protected by Row Level Security and 20+ migrations.
  • A high-performance swipe queue with background processing, local counters for instant feedback, smart caching, and Reanimated-based UI to keep heavy interactions at 60fps.
  • Convergence detection for nomads heading to the same locations, multi-intent priority filtering, and compatibility scoring based on shared interests and lifestyle.
  • RevenueCat feature gating, real-time chat sync, theme engine with instant switching across 5+ schemes, and safety tooling for blocking, reporting, and face verification.
Roamly discovery screen showing a swipe card with a traveller's profile.
The discovery feed: a swipe queue with local counters for instant feedback, smart caching, and convergence detection layered into the ranking.

How I built it

The stack is Expo and React Native with expo-router, Reanimated v3 for the swipe and animation surface, Supabase for the database, auth, and real-time channels, RevenueCat for subscription gating, and TypeScript end to end with auto-generated types from the database schema. State is split across five contexts (Auth, User, Theme, Subscription, Location) instead of one global store, so each screen only re-renders against the slice it actually reads.

The swipe queue

The swipe queue went through three major revisions. Version one wrote to Supabase on every swipe and stuttered. Version two batched writes but lost swipes when the network dropped mid-session. Version three is what shipped: a local counter that updates instantly, a background processor that drains the queue into the database, and a smart cache that pre-fetches the next batch of candidates before the user runs out. The Reanimated layer runs animations on the UI thread, so the database round-trip never blocks the card transition.

Why RLS was the unblocker, not the bottleneck

Supabase Row Level Security gets a reputation for slowing you down on day one. It's the opposite over a project's lifetime: every new screen ships with the security model already in place, every join clears the same policy filter, and you never write 'check the user' in code. With 25+ tables, that discipline was the only reason the codebase stayed sane.

Roamly friends and connections screen showing mutual travellers and verification badges.
Connections view: verification badges come from community vouching with an automatic threshold, so trust is earned without a single moderator in the loop.

What was hard

Three things took real time. First, keeping swipe animations at 60fps while the queue, the cache, and the realtime channel were all firing at once: that was solved by pushing every animation onto Reanimated's UI thread and keeping the JS thread for queue drains only. Second, designing a verification system that resists abuse without becoming a moderation queue: the answer was community vouching with a threshold that auto-verifies once a user collects enough vouches from already-verified accounts. Third, subscription gating without polluting every component: a single useFeatureGate hook reads RevenueCat state from the Subscription context and returns a boolean, so feature checks stay one line.

Roamly messages screen with real-time conversations.
Messages run through Supabase realtime channels with optimistic updates, so the UI never waits for the server before showing a sent bubble.

What I cut

Voice rooms, gift economy, and a 'pen-pal mode' all sat on the wall. None survived the cut to ship. The product is stronger because the features that did ship are the ones a nomad would actually open the app for: who's heading where I'm going, can I trust them, can we talk.

What I learned

  • Optimistic local state plus background sync beats waiting on a database round-trip every single time, for chat and for swipes.
  • Splitting global state into five small contexts is cheaper to reason about than one big store, especially when Theme and Location update on different cadences.
  • Auto-generated TypeScript types from the Supabase schema catch more bugs at compile time than any test suite I would have written in the same hours.
  • Community design matters as much as code. A social app is whatever the verification rules let in.

What's next

Immediate: beta testing with real users, push notifications for matches and messages, expanded moderation with automated content filtering, App Store and Play Store submission, and performance work for lower-end Android devices. Next: Atlas AI for intelligent route convergence (the integration is wired up and commented out for V1), video prompts on top of voice prompts (infrastructure already in place), group events and shared itineraries, and calendar integration for meetup scheduling.

The long-term goal is a privacy-aware social platform that adapts to different lifestyles without forcing people into predefined boxes, whether the connection is romance, friendship, collaboration, or community.
Related project

Roamly: Social Discovery Platform for Modern Nomads (RevenueCat Shipyard: Creator Contest)

View the project