Back to Portfolio
iOS and Android Mobile App · 2025

Campfire RSVP

Cross-platform group planning built to turn chat into commitment.

Campfire RSVP screenshot

Overview

Campfire RSVP started from a recurring failure mode in group chats: plenty of interest, very little commitment. I built the app to test whether a dedicated mobile flow could hold the full planning loop in one place - invite, RSVP, discussion, and last-minute updates. As a solo build, it let me own the product and technical surface end to end, from auth and data modeling to store release and OTA updates.

The Problem

Text threads are great for conversation but poor systems of record. Once a plan starts moving, details get buried, attendance gets fuzzy, and nobody knows whether an event is actually happening. The real challenge was not adding more event fields; it was making coordination feel lighter than staying in iMessage.

Key Decisions

  • I chose React Native and Expo so I could keep one product surface in sync across iOS and Android while still moving at solo-build speed.
  • I used Supabase instead of a custom API because auth, Postgres, realtime, and edge functions covered the product's needs with less operational overhead.
  • I modeled circles and plans as first-class entities, then pushed access control into row-level security so permissions lived with the data rather than scattered across clients.
  • I treated deep linking as core product infrastructure, not polish, because invites only work if the handoff from message to app is reliable.
  • I built testing into the release process with unit coverage around core logic, integration coverage around stateful flows, and Maestro coverage for high-risk end-to-end journeys.
  • I leaned on OTA updates for UI and logic fixes so early iteration was not gated by store review.

Technical Highlights

Real-Time Auth Architecture

The hardest reliability problem was auth, not UI. Mobile OAuth flows can return stale callbacks or collide with platform link handling, especially on Android. I used a generation counter to discard outdated auth results and kept Supabase auth callback handling synchronous to avoid lock contention in gotrue-js.

Cross-Platform Mobile

I aimed for one product surface, not forced visual sameness. Most code is shared, but I used platform-specific paths where native behavior mattered, including Apple Sign In, keyboard handling, haptics, and safe-area quirks. I also used Maestro to cover critical end-to-end flows across platforms so auth, RSVP, and navigation regressions were easier to catch before release.

Push Notifications & Server State

I treated notification discipline as a product feature. Edge Functions handle fan-out, while React Query keeps the client fast with optimistic RSVP updates and predictable cache invalidation. The rule was simple: notify only when a change affects a person's actual plan.

Testing & Release Confidence

Because the app spans auth, realtime state, deep links, and platform-specific behavior, I invested in layered test coverage instead of relying on manual QA. Unit tests protect business logic, integration tests cover multi-step client behavior, and Maestro exercises critical end-to-end flows before release.

Offline-Resilient Data Layer

Perceived speed matters more than theoretical freshness in a consumer app. React Query persistence lets the app open from cache, recover in the background, and clear state cleanly on sign-out. I also added recovery paths for the common mobile case where auth is ready before dependent profile data is.

Tech Stack

React NativeExpoTypeScriptSupabaseReact QueryExpo RouterMaestroUnit & Integration TestingPush Notifications

Tradeoffs & Next Steps

  • Expo gave me release speed and a smaller operational surface, but it also forced discipline about when native escapes were truly worth the complexity.
  • Real-time coordination improves responsiveness, but it can easily create noisy state updates and noisy notifications if the event model grows too broad.
  • If I keep investing in the product, the next engineering push is instrumentation around invite conversion and RSVP completion, not expanding feature surface area.

Outcome

The result is a shipped consumer mobile app on both stores with an architecture I can keep moving quickly. The biggest engineering lesson was that mobile product quality comes from reliability at the edges - auth handoffs, deep links, cache recovery, notification discipline, and polished cross-platform behavior.