How zetorai/sprig works
1. Repo shape: a mobile-first product with a Supabase backend
- This is a monorepo centered on apps/mobile, a React Native + Expo app, with supabase/ providing the backend schema, auth, storage, and server-side functions.
- packages/shared holds cross-cutting types/constants so the mobile app and backend stay aligned.
2. Client entry and app shell
- The mobile app boots through apps/mobile/index.ts and App.tsx.
- Global app concerns are assembled in src/providers and src/navigation: auth state, query/cache setup, theme, and screen routing.
3. Feature-oriented mobile structure
- Most UI is organized by domain under src/features/: auth, onboarding, feed, editor, profile, search, and settings.
- This suggests a vertical-slice architecture where each feature owns its screens and local logic rather than a single large shared app layer.
4. Shared UI and local interaction logic
- Reusable visual pieces live in src/components such as buttons, inputs, avatar, meme card/canvas, and error boundary.
- Feature-specific behavior is split into hooks and helper modules like useFeed, useEngagement, useMemeCardActions, useOnboarding, and reactionLogic, which keeps screens thin and delegates state/business logic downward.
5. Client-side data access layer
- src/lib/api/* is the app’s backend boundary: separate modules for feed, memes, comments, likes, reactions, lineage, profile, search, reports, uploads, templates, GDPR, and social/stoks-related access.
- src/lib/supabase.ts is the core client connector, while queryClient.ts indicates cached request orchestration on the app side.
- This split implies screens call feature hooks, hooks call API wrappers, and those wrappers are the only layer that talks directly to Supabase or functions.
6. Core product flow: create, remix, and lineage
- The editor screens and MemeCanvas are the center of the product loop: a user starts from a template or an existing meme, edits locally, then persists a new post.
- lineage support is a first-class concern, not an afterthought: each remix keeps a parent/child relationship so the app can render “remixed from” and tree-like browsing later.
- The feed and meme detail surfaces consume that lineage data to show the origin and branching history of a meme.
7. Media pipeline and storage
- Media handling is split between client-side rendering/capture and server storage.
- The README indicates react-native-skia / react-native-view-shot for rendering the meme image on device, then uploads routes push the generated asset to Supabase Storage.
- Supabase Storage, plus CDN delivery, is the durable media boundary for the app’s image-heavy content.
8. Social/feed pipeline
- feed, likes, comments, reactions, reports, and engagement form the interaction graph around each meme.
- useFeed and useEngagement suggest the feed is a data-driven surface with optimistic updates or cached interactions, while MemeCard and MemeDetailScreen are the primary presentation points.
- search and profile are secondary read paths over the same underlying social objects.
9. Backend: Supabase as the system of record
- supabase/migrations contains the actual schema evolution and policy layer, including initialization, feed ranking, storage, v2 social features, signup profile behavior, and direct posting.
- This means Postgres is the authoritative store for users, memes, relationships, engagement, and moderation state, with RLS likely controlling access at the table boundary.
- supabase/seed.sql supports local development and reproducible test data.
10. Server-side functions for trust and moderation
- supabase/functions includes moderate-meme and delete-account, which are the main backend execution points beyond raw database access.
- Moderation is explicitly separated from the client, matching the README’s safety model: automated checks and sensitive actions are kept in Edge Functions with secrets stored server-side.
- Account deletion is also centralized, which is important for GDPR/privacy workflows and for safely cascading deletes across related records and storage.
11. Cross-cutting concerns
- observability.ts, share.ts, time.ts, media.ts, and env.ts are utility boundaries used across features.
- The app also has dedicated settings/privacy/help/about screens, which indicates user-facing policy and support flows are part of the product architecture, not just UI polish.
12. Quality and delivery
- Tests exist for utility and feed logic (src/lib/__tests__, src/features/feed/__tests__), so some business rules are intended to be validated outside the UI.
- .github/workflows/ci.yml plus TypeScript/lint/test scripts show the repo is set up for automated validation before deployment.
13. How to diagram it
- A good architecture diagram would place the mobile app on the left, split into feature modules and shared UI.
- In the center, show the client data layer talking to Supabase Auth/Postgres/Storage and to Edge Functions for moderation and destructive actions.
- On the right, show storage/CDN for media and the database as the source of truth, with lineage, feed ranking, reactions, comments, profiles, and reports all modeled as database-backed social data.
Main entry points: index.tsx Navigation · feed.ts API layer · 20260622000000_init.sql Schema · App.tsx App shell
Components 20
Mobile app
React Native + Expo client and feature slices
- App shell · Mobile app bootstrap and root component
apps/mobile/App.tsx - Native entry · Native startup entrypoint
apps/mobile/index.ts - Providers · Auth, cache, and global app state providers
apps/mobile/src/providers/AuthProvider.tsx - Navigation · Screen routing and navigation types
apps/mobile/src/navigation/index.tsx - UI kit · Reusable visual components and canvas rendering
apps/mobile/src/components/MemeCard.tsx - Auth · Sign-in and authentication surface
apps/mobile/src/features/auth/SignInScreen.tsx - Onboarding · First-run setup and profile completion flow
apps/mobile/src/features/onboarding/OnboardingScreen.tsx - Editor · Create and edit meme posts
apps/mobile/src/features/editor/EditorScreen.tsx - Feed · Feed, detail, and lineage browsing
apps/mobile/src/features/feed/FeedScreen.tsx - Profile · User profile surface
apps/mobile/src/features/profile/ProfileScreen.tsx - Search · Discovery and lookup surface
apps/mobile/src/features/search/SearchScreen.tsx - Settings · Account, privacy, help, and app settings
apps/mobile/src/features/settings/SettingsScreen.tsx - Feed logic · Feed data and engagement hooks
apps/mobile/src/features/feed/useFeed.ts - Editor logic · Editor and onboarding behavior hooks
apps/mobile/src/features/editor/CreateScreen.tsx - API layer · Backend-facing client modules for data access
apps/mobile/src/lib/api/feed.ts - Supabase client · Supabase client and cached request orchestration
apps/mobile/src/lib/supabase.ts
Shared package
Cross-cutting types and constants shared by client and backend
- Shared types · Cross-cutting types and constants
packages/shared/src/index.ts
Supabase backend
Database schema, storage, and edge functions
- Schema · Database schema, policies, and ranking logic
supabase/migrations/20260622000000_init.sql - Edge functions · Moderation and account deletion functions
supabase/functions/moderate-meme/index.ts
Connections 29
- Native entry → App shell: starts · Native bootstrap launches the app shell
- App shell → Providers: wraps · Root component assembles global providers
- App shell → Navigation: renders · App shell mounts navigation
- Providers → Navigation: supplies state · Auth and cache context feed routing and screens
- Navigation → Auth: routes to · Navigation exposes auth screen
- Navigation → Onboarding: routes to · Navigation exposes onboarding flow
- Navigation → Editor: routes to · Navigation exposes editor flow
- Navigation → Feed: routes to · Navigation exposes feed and detail views
- Navigation → Profile: routes to · Navigation exposes profile view
- Navigation → Search: routes to · Navigation exposes search view
- Navigation → Settings: routes to · Navigation exposes settings views
- Feed → Feed logic: uses · Feed screens depend on feed and engagement hooks
- Editor → Editor logic: uses · Editor and onboarding screens use local behavior hooks
- Feed → UI kit: uses · Feed surfaces reuse shared cards and avatar pieces
- Editor → UI kit: uses · Editor uses shared canvas and form components
- Auth → UI kit: uses · Auth screen reuses shared inputs and hero UI
- Feed logic → API layer: calls · Feed logic fetches and mutates through API wrappers
- Editor logic → API layer: calls · Editor and onboarding logic persist through API wrappers
- Profile → API layer: reads via · Profile screen consumes backend data through API modules
- Search → API layer: reads via · Search screen queries backend data through API modules
- API layer → Supabase client: uses · API modules use the shared Supabase client
- API layer → Schema: targets · Client data access reads and writes the Postgres schema
- API layer → Edge functions: invokes · Sensitive actions and moderation go through edge functions
- Schema → Edge functions: governs · Functions operate over the database-backed system of record
- Shared types → API layer: aligns · Shared types keep client payloads consistent
- Shared types → Schema: aligns · Shared constants and types mirror backend entities
- Edge functions → Schema: updates · Moderation and account deletion mutate persisted records
- CI → App shell: validates · CI covers the mobile app build and checks
- CI → Schema: validates · CI also validates backend migrations and functions