Skip to content
Gasperi

An appointment platform, built end to end and shipped.

Client

Gasperi Innovations

Year

2026

Role

Founder & Engineer

Stack

  • Expo 54
  • React Native
  • Next.js 16
  • Supabase
  • Stripe Connect
  • RevenueCat
  • Tamagui
  • Turborepo

My own product: a booking platform for service businesses. Businesses manage schedules, staff, and deposits; customers find them and book in real time. Native apps for iOS and Android, a marketing site, a Postgres backend, and the payment rails — designed, built, and shipped solo.

01

Availability is the hard part

Booking looks like a calendar. It isn't. A bookable slot is what's left after you apply a business's weekly schedule, a specific staff member's own schedule, date-specific overrides for closures and holidays, every appointment already on the books, the buffer between appointments, and the minimum notice the business requires — all resolved in the business's timezone, not the phone's.

Getting that wrong doesn't throw an error. It double-books a real person, or quietly hides a slot the business could have sold. So the availability engine is the part of this product I treated as load-bearing: a business day is a calendar date interpreted in the business's timezone, and every slot is derived from that one definition rather than from whatever the device thinks the date is.

The vocabulary is pinned down in writing — schedule, override, slot, business day, cancel window — because the bugs in a booking system are almost always two parts of the code meaning slightly different things by the same word.

02

One codebase, two platforms

The app is React Native and the marketing site is Next.js, sharing a monorepo with the business logic in a single package. Hooks, data fetching, validation, and feature screens live in shared code; native dependencies stay quarantined in the Expo app.

The rule that makes it hold: shared code cannot import from the app. It's a one-way dependency, enforced rather than encouraged, which is why the shared package is still shared eight months in instead of having quietly grown native imports and become app-only code with extra steps.

03

Money and the parts nobody demos

Deposits run through Stripe Connect, so funds settle to the business rather than through me — which keeps me out of being a money transmitter and keeps businesses paid without an intermediary. Subscriptions run through RevenueCat because iOS and Android in-app purchase is not a thing you want to implement twice.

The unglamorous half is most of the work: push reminders through edge functions, account deletion flows because Google Play requires them, deep links into public business profiles, over-the-air updates. Shipping a product means shipping the parts that never make it into a demo.

Next project

Workforce

One codebase, three branded apps, two and a half years.