The mymuaythai.app monorepo has four apps:
All four share one Supabase instance. Here's how we make that work without chaos.
Shared packages
@repo/supabase — Generated types from supabase gen types, shared client config@repo/shared — Business logic, validation schemas (Zod), constants@repo/ui — Shared UI components (limited — mobile and web have different needs)The type generation pipeline
When the schema changes: supabase db push → supabase gen types → all four apps get updated types. One migration, all surfaces updated. TypeScript catches breakage at compile time.
What we don't share
Routing, state management, and most UI. Mobile uses Expo Router + Zustand. Web uses React Router. Admin uses Vite's built-in routing. Trying to share too much across platforms is a trap.
The overhead is worth it
A monorepo adds tooling complexity. But when you fix a bug in a shared validation schema, it's fixed everywhere. When you add a database column, TypeScript tells you every file that needs updating. That compound benefit is enormous.