The problem
Salon software is built for beauty in general, so the parts of hair work that matter — colour formulas, processing time between stages, chair and booth rent — end up in free-text notes. A solo booth renter and an eight-chair salon need the same booking core but very different money flows, and neither wants an enterprise product to get them.
Approach
- Hair-specific rather than all-beauty: services carry variants by hair type, add-ons, and processing stages, and a returning client's colour formula is one click from their profile.
- Multi-tenant: each salon is a tenant with its own public booking page; the client-facing directory is opt-in, off unless a salon turns it on.
- Payments fail closed: a payment function takes money only once the salon's own payout account is verified, and the platform never holds funds it cannot route.
Architecture
- React 18 single-page app on Vite, with Supabase Postgres, Auth, Storage and edge functions behind it. Row-level security scopes every tenant table in the database.
- Staff impersonation for support is audited: an effective-user function records who is really acting, and impersonation starts and stops through its own edge functions.
- Per-salon payouts through Stripe Connect direct charges, so the salon is the merchant of record, with PayPal Multiparty added as a second split-payment rail.
- Twilio for SMS, Resend for email, and two-way calendar sync with Google Calendar and Microsoft 365. Sentry receives source maps at build time, and they are deleted before deploy so the browser never gets original source.
What shipped
- Public booking with service variants, add-ons and processing stages, plus recurring bookings, deposits and no-show fees.
- Colour formula history with version history and a photo-consent gate.
- Commissions, tips, gift cards, memberships and retail point of sale with stylist attribution.
- Duration prediction and waitlist gap-filling, reminder and follow-up sequences, and an installable PWA.
- Tenant data export, cascading tenant deletion, and GDPR data-rights requests.
By the numbers
- Edge functions
- 67
- Database migrations
- 179
- Test files
- 173
Stack
React 18TypeScriptSupabaseStripeTwilio
Building something like this?
Tell us what you're working on and we'll tell you honestly whether we're the right team for it.
Start a conversation