Skip to content

CasTyou — React Native Migration Plan

Generated: 2026-06-15 Scope: Port apps/app (React 18 + Vite SPA) to a native iOS/Android app. Admin portion explicitly excluded. apps/landing (Next.js marketing site) is also out of scope. Source: castyou-frontend monorepo, apps/app/src (~71.7k LOC) and packages/design-system (~7.2k LOC). How to use: Each epic has a Summary (what & why), a Detail (tickets, files, approach), and an Estimate (Claude build effort + recommended model). Tickets use [ ] checkboxes — mark [x] when implemented and reviewed. Read this file before starting any RN work.


Executive Summary

Porting CasTyou to React Native is a UI rebuild with logic reuse, not a code port. The codebase is cleanly layered, which works in our favor:

  • The data/logic layer (~21k LOC: hooks, stores, GraphQL queries, react-query, zustand, i18n) moves over with light changes — these libraries all run in React Native.
  • The presentation layer (~37k LOC of page JSX + the 54-component design system) is rewritten — it is built on Radix UI primitives + Tailwind classes, neither of which renders in React Native.
  • A handful of features are genuinely hard because they depend on browser-only tech: the flier/poster editor (konva/canvas), face liveness (@mediapipe), and all media capture/processing (getUserMedia, file inputs, canvas).

There is no WebView shortcut that yields a real app, and no automated converter for Radix+Tailwind → native.

Total estimate: ~95–135 Claude build-sessions (defined below), sequenced across 16 epics. With a single human reviewing/integrating Claude's output and handling device testing, that maps to roughly 3–6 months of calendar time. The estimate is dominated by the design-system rebuild and the three hard features.


Estimation Methodology

Estimates are expressed in Claude build-sessions, not human-days.

1 Claude session ≈ one focused agentic build-and-verify cycle — Claude writes/migrates a coherent slice, runs typecheck/tests, and a human reviews and integrates it. Roughly half a day of supervised wall-clock per session.

Each epic also carries a complexity tier and a recommended model:

TierMeaning
MechanicalHigh-volume, pattern-repetitive conversion (JSX primitives, imports, className → style). Low ambiguity.
ModerateFeature logic + UI with some judgment, but a clear target shape.
HardNative modules, platform APIs, or architectural design with real unknowns.
ResearchNo drop-in equivalent exists; requires spiking a library + iterating on a device.

Model guidance

  • Fable 5 — use for Mechanical and most Moderate work: bulk JSX-primitive conversion, className → StyleSheet/NativeWind, repetitive page migration, mirroring component APIs. Faster output and cheaper at high volume; quality is on par for well-specified mechanical transforms.
  • Opus 4.8 — use for Hard and Research work, plus all up-front architecture: foundations, shared-package extraction, navigation modeling, the native modules (skia flier editor, vision-camera liveness, media pipeline), and any ambiguous design decisions. Use it to write the pattern/spec once, then hand the repetitive application to Fable 5.

A practical pattern throughout: Opus 4.8 designs the template for an epic → Fable 5 applies it across the many files.


Portability Summary

LayerSize (non-admin)DispositionTier
Data/logic — hooks, stores, gql, query client, i18n~21k LOC🟢 Port with light editsModerate
Routing (react-router-dom, 135 files)🟡 Swap → React NavigationMechanical
Page JSX (26 areas, ~90 routes)~25.5k LOC🔴 Rewrite UIMechanical→Moderate
App components~4k LOC🔴 Rewrite UIModerate
Design system (54 components, Radix + Tailwind)~7.2k LOC🔴 Full native rebuildHard
Flier editor (konva/react-konva)~3 files🔴 Rebuild on SkiaResearch
Face liveness (@mediapipe/tasks-vision)1 file🔴 Rebuild on vision-camera/MLKitResearch
Media capture/processing (getUserMedia, file input, canvas)~6 files + DS🔴 Replace with native modulesHard
Drag & drop (@dnd-kit)1 file🟡 Swap → reanimated/gesture-handlerModerate
PDF export (jspdf)1 file🟡 Swap → RN PDF or server-sideModerate

Epic Roll-Up

EpicTitleTierSessionsLead model
RN-0Foundations & ToolingHard4–6Opus 4.8
RN-1Shared Logic Extraction (@castyou/core)Moderate5–7Opus 4.8
RN-2Design System NativeHard16–22Opus → Fable
RN-3Navigation & App ShellHard5–7Opus 4.8
RN-4Auth & OnboardingModerate5–7Opus → Fable
RN-5Feed & SocialModerate6–8Fable 5
RN-6JobsModerate9–12Fable 5
RN-7Profiles & PortfolioModerate7–9Fable 5
RN-8Discovery & SearchModerate4–6Fable 5
RN-9Messaging & Notifications (+ Push)Hard5–7Opus → Fable
RN-10Groups, Agency, CasTars, Bounty, Settings, MiscModerate7–9Fable 5
RN-11Media Capture & ProcessingHard6–8Opus 4.8
RN-12Flier / Poster Editor (Skia)Research7–11Opus 4.8
RN-13Face Liveness VerificationResearch5–8Opus 4.8
RN-14Export & PDFModerate2–3Opus → Fable
RN-15Release EngineeringHard4–6Opus 4.8
Total97–136

Epic RN-0 — Foundations & Tooling

Summary

Stand up the React Native project, build system, and monorepo wiring so every later epic has a place to land. This is the keystone: decisions here (Expo vs bare, NativeWind vs StyleSheet, navigation lib) cascade through all 15 other epics, so it must be done deliberately with the strongest model.

Detail

  • [ ] RN-FOUND-001 — Scaffold apps/mobile as an Expo (managed) app inside the existing pnpm/Turbo workspace; wire Metro to resolve workspace packages.
  • [ ] RN-FOUND-002 — Decide and lock the styling strategy: NativeWind (preserves Tailwind class strings → faster page migration) vs StyleSheet + token objects. Recommendation: NativeWind, to maximize reuse of existing className strings during page migration.
  • [ ] RN-FOUND-003 — Pick navigation lib (React Navigation recommended over Expo Router given the existing imperative route tree) and add base TypeScript config, ESLint, and Metro/Babel for the monorepo.
  • [ ] RN-FOUND-004 — Secure storage primitive (expo-secure-store / Keychain) + MMKV for non-secret persisted state, to replace localStorage (12 call sites) and the auth-store persistence.
  • [ ] RN-FOUND-005 — Environment/config (VITE_API_URL → Expo extra/env), and CI for typecheck + EAS build smoke.

Estimate

Tier: Hard · 4–6 sessions · Opus 4.8. Architectural, high-leverage, low line-count. Do not delegate to Fable 5 — wrong foundation decisions are expensive to unwind.


Epic RN-1 — Shared Logic Extraction (@castyou/core)

Summary

Extract the platform-agnostic data/logic layer into a new shared workspace package consumed by both apps/app (web) and apps/mobile. This is the single highest-ROI move: ~21k LOC of hooks, stores, queries, and the GraphQL client become write-once, run-both-platforms, and it prevents web/mobile from forking.

Detail

  • [ ] RN-CORE-001 — Create packages/core; move lib/queries, gql/, lib/queryClient.ts, lib/queryKeys.ts, stores/, and platform-agnostic hooks/ (the bulk of the 82 hooks).
  • [ ] RN-CORE-002 — Abstract platform-specific seams behind injected adapters: storage (localStorage ↔ SecureStore/MMKV), token source in graphqlClient.ts, and import.meta.env → injected config.
  • [ ] RN-CORE-003 — Move GraphQL transport (graphql-request) + subscriptions (graphql-ws / wsClient.ts); verify WS works under React Native's networking.
  • [ ] RN-CORE-004 — Move i18n core (i18n.ts); swap i18next-browser-languagedetector for an RN locale detector. Keep @castyou/i18n strings shared.
  • [ ] RN-CORE-005 — Repoint apps/app (web) imports at @castyou/core and confirm web is green (proves the extraction didn't break the existing app).

Estimate

Tier: Moderate · 5–7 sessions · Opus 4.8 (adapter/seam design needs judgment; the mechanical moves can drop to Fable 5). The web app regressing is the main risk — keep web CI green as the gate.


Epic RN-2 — Design System Native (@castyou/design-system-native)

Summary

Rebuild all 54 design-system components on native primitives (View/Text/Pressable/Image) with a styling solution that mirrors the existing component API (same prop names/variants) so downstream page migration is predictable. This is the largest single epic — every page depends on it — and the Radix-based overlay components (Dialog, Select, Dropdown, Toast, Tooltip) have no RN equivalent and must be reimplemented.

Detail

Tokens & theming

  • [ ] RN-DS-001 — Port tokens/ to a native theme object; reproduce the brand gradients, glow box-shadows, and backdrop-blur (heavily used — see Button.tsx) via expo-linear-gradient, shadow approximation, and expo-blur.

Primitive components (Fable 5, mostly mechanical, API-mirrored)

  • [ ] RN-DS-002 — Button, Badge, Chip, Card, Avatar, Skeleton, Input, Textarea, Switch, Tabs, ProgressRing, StatCard, StepIndicator, EmptyState, Pagination.
  • [ ] RN-DS-003 — Domain cards: JobCard, TalentCard, PetCard, PostCard, GroupCard, SuggestionCard, SystemPostCard, JobFlierCard, JobSwipeCard, FollowButton, ReportButton.

Radix-backed overlays & complex widgets (Opus 4.8, reimplement from scratch)

  • [ ] RN-DS-004 — Modal/Dialog, ConfirmDialog, Select, MultiSelect, FilterSheet → native bottom-sheets/modals + pickers.
  • [ ] RN-DS-005 — Toast (replace @radix-ui/react-toast with an RN toast/notifier), Tooltip, dropdown menus, LanguageSwitcher, ThemeToggle.
  • [ ] RN-DS-006 — Data-heavy: DataTable, RangeSlider, SearchBar, GlitterBackground.
  • [ ] RN-DS-007 — Media components (overlap with RN-11): MediaGallery, MediaPlayer, VideoRecorder, ImageCropper, FileUpload — native shells here, native module wiring in RN-11.

Estimate

Tier: Hard · 16–22 sessions. Split the work: Opus 4.8 writes the theming foundation (RN-DS-001) and the overlay reimplementations (RN-DS-004/005/006), then Fable 5 mass-produces the primitive and card components against that template. Storybook → an in-app component gallery screen for visual QA.


Epic RN-3 — Navigation & App Shell

Summary

Re-model the 98-route react-router-dom tree (referenced in 135 files) as React Navigation stack/tab navigators, and rebuild the app shells (AppShell, ProtectedShellLayout, role guards) as native navigation containers with a tab bar. Deep linking for share/handle URLs is set up here.

Detail

  • [ ] RN-NAV-001 — Map the route tree → navigator hierarchy (root stack, authenticated tab navigator, modal stack); document the mapping.
  • [ ] RN-NAV-002 — Rebuild AppShell.tsx and ProtectedShellLayout.tsx (auth/role/pet-owner/agency guards) as navigation guards + a native tab bar.
  • [ ] RN-NAV-003 — Port DocumentTitleProvider/page-title behavior to native header titles (lib/pageTitles.ts).
  • [ ] RN-NAV-004 — Deep linking + universal/app links for handle routes (/talent/:handle, /producer/:handle, share links); a codemod for the useNavigate/Link/useParams → React Navigation equivalents across the 135 files.
  • [ ] RN-NAV-005 — Port error boundaries (ErrorBoundary.tsx) and the account-blocked gate (AccountBlockedPage.tsx).

Estimate

Tier: Hard · 5–7 sessions. Opus 4.8 designs the navigator hierarchy and writes the router-API codemod pattern; Fable 5 applies the codemod across the 135 files. Guard/deep-link logic needs careful review.


Epic RN-4 — Auth & Onboarding

Summary

First real feature surface end-to-end: login/register, social auth, and the onboarding flow. Validates the whole stack (core + DS-native + navigation) before the high-volume feature epics. (~1.7k LOC: auth + onboarding.)

Detail

  • [ ] RN-AUTH-001 — LoginPage, RegisterPage on DS-native; secure token storage via RN-FOUND-004.
  • [ ] RN-AUTH-002 — Social auth (socialAuth.ts) → native OAuth (expo-auth-session / Firebase Auth RN); 3 firebase web-SDK call sites swap to @react-native-firebase.
  • [ ] RN-AUTH-003 — OnboardingPage multi-step flow (1.1k LOC) on native StepIndicator.
  • [ ] RN-AUTH-004verify flow scaffolding (liveness deferred to RN-13).

Estimate

Tier: Moderate · 5–7 sessions. Opus 4.8 for the OAuth/native-auth seam (RN-AUTH-002), Fable 5 for the page UI. Expect extra iteration here since it's the first integration of all foundations.


Epic RN-5 — Feed & Social

Summary

The social core: publication feed, feed tabs, social graph (follow/suggestions/search-feeds), post detail, owner post management, and the composer (sans native media capture, which lands in RN-11). (~1.4k LOC across feed + social.)

Detail

  • [ ] RN-FEED-001 — Feed list + tabs + PostCard/SystemPostCard rendering on DS-native (FlatList virtualization replacing web scroll).
  • [ ] RN-FEED-002 — Post detail, likes/comments, owner actions (PostOwnerActionsModal), report content.
  • [ ] RN-FEED-003 — Composer & picker UI shells (ComposerPage.tsx, PickerPage.tsx) — wired to native capture in RN-11.
  • [ ] RN-FEED-004 — Social graph: follow, suggestions, unified search results, handles.

Estimate

Tier: Moderate · 6–8 sessions · Fable 5. Mostly list/card UI over already-ported hooks. FlatList performance tuning is the main native-specific concern.


Epic RN-6 — Jobs

Summary

The largest feature area (~8k LOC): role-dispatched job board, public job pages, create/edit (incl. pet jobs), the apply flow, invite-to-job, and match breakdown. High line-count but pattern-repetitive once DS-native and forms are settled.

Detail

  • [ ] RN-JOBS-001 — JobsRouter + role-dispatched listing (talent match grid / producer table → native lists).
  • [ ] RN-JOBS-002 — Job detail (PublicJobPage, union resolver) + MatchBreakdown.
  • [ ] RN-JOBS-003 — Job create/edit + PetJob create/edit (large multi-section forms → native form components).
  • [ ] RN-JOBS-004 — Apply flow (JobApplyPage) incl. portfolio/folder directory selection.
  • [ ] RN-JOBS-005 — InviteToJobModal, shortlist/swipe actions (JobSwipeCard + gesture handling).
  • [ ] RN-JOBS-006 — Flier entry points link to RN-12 (editor itself is its own epic).

Estimate

Tier: Moderate · 9–12 sessions · Fable 5. The big forms are the time sink; have Opus 4.8 define one canonical native-form pattern first, then Fable 5 replicates. Swipe cards need reanimated/gesture-handler.


Epic RN-7 — Profiles & Portfolio

Summary

Talent, producer, and pet-owner profiles + edit pages, plus the unified portfolio (MediaItem) and folders. Includes public share-link profile views. (~6.5k LOC across profile, talent, producer, petowner, folders.)

Detail

  • [ ] RN-PROF-001 — ProfilePage + TalentProfilePage / TalentEditPage (largest profile surface).
  • [ ] RN-PROF-002 — ProducerProfilePage / ProducerEditPage (handle links, structured portfolioLinks, open-roles section).
  • [ ] RN-PROF-003 — PetOwner profile + pets list/detail/edit (PetEditPage — image picker via RN-11).
  • [ ] RN-PROF-004 — Unified Portfolio (MediaItem grid, image/video/link, public/private) + Folders (single-membership, Uncategorized) with native gallery.
  • [ ] RN-PROF-005 — Portfolio drag-to-reorder (@dnd-kit → reanimated/gesture-handler).

Estimate

Tier: Moderate · 7–9 sessions · Fable 5. DnD reorder (RN-PROF-005) is the one Hard sub-task — pull in Opus 4.8 for the gesture pattern.


Summary

Discover feed (AI match), talent discovery, and unified search. The swipe-based discover interaction needs native gestures.

Detail

  • [ ] RN-DISC-001 — DiscoverPage (AI match feed) with swipe interaction (JobSwipeCard / gesture-handler).
  • [ ] RN-DISC-002 — TalentDiscoveryPage grid + filters (FilterSheet → bottom sheet).
  • [ ] RN-DISC-003 — Unified SearchPage (tabs, results) + SearchBar native.

Estimate

Tier: Moderate · 4–6 sessions · Fable 5. Reuses card/list/filter patterns from RN-5/6/7; swipe gesture is the only novel bit.


Epic RN-9 — Messaging & Notifications (+ Push)

Summary

Real-time messaging (GraphQL subscriptions over WS), the notifications center, and — net-new for mobile — native push notifications. Per project rule, received-message unread state lives only in Messages + nav badge; no message notifications.

Detail

  • [ ] RN-MSG-001 — Conversation list + thread UI on native; verify graphql-ws subscriptions over RN networking + reconnect/background behavior.
  • [ ] RN-MSG-002 — Per-conversation + nav-badge unread state (no message notifications, per feedback_notifications).
  • [ ] RN-NOTIF-001 — Notifications center + NotificationBell → native badge.
  • [ ] RN-PUSH-001Native push (Expo Notifications / FCM+APNs): device-token registration, backend hook, deep-link-on-tap. (Net-new; coordinate with backend — current notifications are in-app only.)

Estimate

Tier: Hard · 5–7 sessions. Opus 4.8 for WS-over-RN reliability (RN-MSG-001) and push infra (RN-PUSH-001); Fable 5 for the chat/notification list UI. Push requires backend coordination and is the schedule risk.


Epic RN-10 — Groups, Agency, CasTars, Bounty, Settings & Misc

Summary

The remaining smaller feature areas, batched: Groups, Agency tier, CasTars currency + widget, Bounty Hunter, Pricing, Settings, Support/Report-bug, Discover-adjacent pages, and impersonation (kept minimal, non-admin). (~4.5k LOC combined.)

Detail

  • [ ] RN-MISC-001 — Groups (list, detail, activity feed, events, group apply).
  • [ ] RN-MISC-002 — CasTars (wallet/ledger pages, CaStarsWidget) + Bounty (list, create, detail) + UpgradeModal.
  • [ ] RN-MISC-003 — Agency tier pages.
  • [ ] RN-MISC-004 — Settings, Pricing, Support, ReportBugModal.
  • [ ] RN-MISC-005 — Impersonation banner (non-admin user-facing portion only) + account-status enforcement surfaces.

Estimate

Tier: Moderate · 7–9 sessions · Fable 5. All standard list/form/card UI over ported hooks; batch aggressively.


Epic RN-11 — Media Capture & Processing

Summary

Replace every browser media API with native modules: camera/photo capture, image cropping, video recording, file/document upload, video thumbnail generation, and post-image baking. This unblocks the composer, profile/pet edits, and the DS media components. Foundational native-module work — do it before the features that consume it ship.

Detail

  • [ ] RN-MEDIA-001 — Camera + photo/video capture (react-native-vision-camera or expo-camera) replacing getUserMedia/MediaRecorder.
  • [ ] RN-MEDIA-002 — Image picker + cropper (replace ImageCropper web impl) and document/file upload (replace <input type=file>).
  • [ ] RN-MEDIA-003 — Video thumbnail generation (generateVideoThumbnail.ts) and post-image baking (bakePostImage.ts) — canvas → Skia/native.
  • [ ] RN-MEDIA-004 — Wire S3 presigned-URL upload pipeline to native file refs; createObjectURL → native URIs.
  • [ ] RN-MEDIA-005 — DS MediaPlayer/MediaGallery/VideoRecorder native impls (expo-av/video).

Estimate

Tier: Hard · 6–8 sessions · Opus 4.8. Native modules, permissions, and platform quirks (iOS vs Android) require real device testing — the part Claude can't fully self-verify, so budget human device-loop time.


Epic RN-12 — Flier / Poster Editor (Skia)

Summary

Rebuild the job flier/poster editor — currently konva + react-konva canvas compositing with AI-generated layers — on @shopify/react-native-skia. There is no drop-in port; this is a from-scratch reimplementation of a complex interactive canvas. Highest-uncertainty epic.

Detail

  • [ ] RN-FLIER-001 — Spike Skia: reproduce layer model from FlierCanvas.tsx and renderFlier.ts (text, image, gradient layers; defaults in flierCanvasDefaults.ts).
  • [ ] RN-FLIER-002 — Interactive editing: drag/scale/select layers via gesture-handler + reanimated.
  • [ ] RN-FLIER-003 — AI layer prompt input (FlierAIPromptInput) + render-to-image export (Skia snapshot → upload).
  • [ ] RN-FLIER-004 — Parity pass against web output (FlierThumbnail, JobFlierCard previews).

Estimate

Tier: Research · 7–11 sessions · Opus 4.8. Wide range reflects genuine unknowns in Skia gesture/text fidelity. Consider scoping a read-only flier viewer for v1 and deferring full editing if schedule-constrained.


Epic RN-13 — Face Liveness Verification

Summary

Rebuild identity liveness — currently @mediapipe/tasks-vision running WASM face landmarks in the browser (LivenessChallenge.tsx) — using a native camera + on-device face detection (react-native-vision-camera frame processors + ML Kit / VisionCamera face-detector). Native, on-device, and security-sensitive.

Detail

  • [ ] RN-LIVE-001 — Spike vision-camera frame processor + ML Kit face detection; confirm landmark/challenge signal availability on both platforms.
  • [ ] RN-LIVE-002 — Port challenge logic (blink/turn prompts) and pass/fail thresholds from the web implementation.
  • [ ] RN-LIVE-003 — Wire into the verify flow (RN-AUTH-004) + backend verification submission.
  • [ ] RN-LIVE-004 — On-device performance + anti-spoofing review.

Estimate

Tier: Research · 5–8 sessions · Opus 4.8. Depends on RN-11 camera foundation. Security-sensitive — over-budget review time; device testing mandatory.


Epic RN-14 — Export & PDF

Summary

Replace jspdf-based pitch/sheet export (face sheet, full info sheet, presentation deck) — jspdf is browser-oriented in RN. Either swap to an RN PDF library or move generation server-side (often the cleaner long-term answer).

Detail

  • [ ] RN-EXPORT-001 — Decide RN-side PDF lib vs server-side generation for ExportPitchModal.
  • [ ] RN-EXPORT-002 — Implement chosen path + native share-sheet for the resulting file.

Estimate

Tier: Moderate · 2–3 sessions. Opus 4.8 for the build-vs-server decision, Fable 5 for implementation. Server-side generation likely turns this into mostly a share-sheet wiring task.


Epic RN-15 — Release Engineering

Summary

Everything required to ship to stores: EAS build profiles, code signing, App Store / Play Store listings + review, OTA update channel, crash reporting, and final deep-link/universal-link verification. Largely outside Claude's execution loop (accounts, signing, store review) but Claude can prepare config and assets.

Detail

  • [ ] RN-REL-001 — EAS build/submit profiles (dev/preview/prod), code signing (certs/provisioning), app icons & splash.
  • [ ] RN-REL-002 — Crash/error reporting RN SDK (mirror existing web error bus → native).
  • [ ] RN-REL-003 — OTA update channel (EAS Update) + version/rollback policy.
  • [ ] RN-REL-004 — Store listings, privacy disclosures (camera/photos/push), review submission.
  • [ ] RN-REL-005 — End-to-end deep-link/universal-link verification on device.

Estimate

Tier: Hard · 4–6 sessions · Opus 4.8. Much of the wall-clock is store review and account setup (human-only); Claude's share is config + reporting integration.


Suggested Sequencing

  1. Foundation phase (blocking): RN-0 → RN-1 → RN-2 → RN-3. Nothing else can start meaningfully until DS-native and navigation exist.
  2. Vertical slice: RN-4 (Auth/Onboarding) to validate the full stack on a device.
  3. Feature fan-out (parallelizable across sessions): RN-5, RN-6, RN-7, RN-8, RN-10 — mostly Fable 5, over the shared core.
  4. Native-module track (run alongside, gates dependent features): RN-11 first, then RN-9 (push), RN-12, RN-13, RN-14.
  5. Ship: RN-15.

Risk Register

  • Design system is the critical path — every page waits on RN-2. Front-load it and freeze its component API early.
  • The three research epics (RN-12 Skia, RN-13 liveness, RN-11 media) carry the most schedule variance and require real-device testing Claude cannot self-verify — budget human device-loop time, and consider de-scoping flier editing to a viewer for v1.
  • Web/mobile fork risk — mitigated only if RN-1 (@castyou/core) lands first and web is migrated onto it; otherwise every later backend change is implemented twice.
  • Push notifications (RN-9) need backend changes — current notifications are in-app only.
  • Estimates assume a competent human reviewing/integrating each Claude session and owning device QA. They are build-effort, not unattended-automation, figures.

Roadmap Mirror — RN Epics (moved from the product roadmap)

Trackable epic mirror that previously lived in the product roadmap. The detailed plan is above; this is the checklist view.

Track: Port apps/app (React 18 + Vite SPA) to a native iOS/Android app via React Native. Admin and apps/landing (Next.js marketing) are excluded. This is a UI rebuild with logic reuse, not a code port — there is no WebView shortcut and no automated Radix+Tailwind→native converter. Full per-ticket detail (files, approach, model guidance): see CASTYOU-REACT-NATIVE-MIGRATION.md (generated 2026-06-15). The epics below are the trackable roadmap mirror; that doc is the source of truth for file lists and rationale. Status: Planning only — not started (all tickets [ ]). Estimated ~97–136 Claude build-sessions (~3–6 months calendar with one human reviewing/integrating + owning device QA). Staleness note: the plan predates the 2026-06-16 realignment ([[Match Engine]] Epic 42 replaced job apply with swipe-to-match). Treat apply-flow references (e.g. RN-JOBS-004 JobApplyPage) as the match flow. Estimation unit: 1 session ≈ one focused agentic build-and-verify cycle (~half a day supervised). Model split: Opus 4.8 designs foundations/hard/research + writes each epic's template; Fable 5 mass-applies the template across the many files.

Roll-up

EpicTitleTierSessionsLead model
RN-0Foundations & ToolingHard4–6Opus 4.8
RN-1Shared Logic Extraction (@castyou/core)Moderate5–7Opus 4.8
RN-2Design System NativeHard16–22Opus → Fable
RN-3Navigation & App ShellHard5–7Opus 4.8
RN-4Auth & OnboardingModerate5–7Opus → Fable
RN-5Feed & SocialModerate6–8Fable 5
RN-6JobsModerate9–12Fable 5
RN-7Profiles & PortfolioModerate7–9Fable 5
RN-8Discovery & SearchModerate4–6Fable 5
RN-9Messaging & Notifications (+ Push)Hard5–7Opus → Fable
RN-10Groups, Agency, CasTars, Bounty, Settings, MiscModerate7–9Fable 5
RN-11Media Capture & ProcessingHard6–8Opus 4.8
RN-12Flier / Poster Editor (Skia)Research7–11Opus 4.8
RN-13Face Liveness VerificationResearch5–8Opus 4.8
RN-14Export & PDFModerate2–3Opus → Fable
RN-15Release EngineeringHard4–6Opus 4.8
Total97–136

Suggested sequencing

  1. Foundation (blocking): RN-0 → RN-1 → RN-2 → RN-3 — nothing else starts meaningfully until DS-native + navigation exist.
  2. Vertical slice: RN-4 (Auth/Onboarding) to validate the full stack on a device.
  3. Feature fan-out (parallelizable, mostly Fable 5 over the shared core): RN-5, RN-6, RN-7, RN-8, RN-10.
  4. Native-module track (gates dependent features): RN-11 first, then RN-9 (push), RN-12, RN-13, RN-14.
  5. Ship: RN-15.

Risk register

  • Design system (RN-2) is the critical path — every page waits on it; front-load it and freeze its component API early.
  • The three research/native epics (RN-11 media, RN-12 Skia, RN-13 liveness) carry the most schedule variance and need real-device testing Claude cannot self-verify — budget human device-loop time; consider de-scoping flier editing to a read-only viewer for v1.
  • Web/mobile fork risk — mitigated only if RN-1 (@castyou/core) lands first and the existing web app is migrated onto it (RN-CORE-005); otherwise every later backend change is implemented twice.
  • Push notifications (RN-9) need backend changes — current notifications are in-app only ([[Notifications vs Messages]]).

Epic RN-0 — Foundations & Tooling

Tier: Hard · 4–6 sessions · Opus 4.8. Stand up the RN project, build system, and monorepo wiring so every later epic has a place to land. Keystone — decisions here cascade through all 15 other epics; do not delegate.

✅ Stack decided (user, 2026-06-28): Expo managed + Dev Client (EAS builds + OTA; config plugins for native modules — Dev Client, not Expo Go) · NativeWind (Tailwind className strings keep working → minimal style rewriting) · React Navigation (maps the imperative route tree; mechanical codemod from react-router) · expo-secure-store (auth token) + MMKV (non-secret persisted state). Push later (RN-9) = Expo Notifications.

🛠 Scaffolded 2026-06-28 (apps/mobile): Expo SDK 56 / RN 0.85.3 / React 19.2.3 / TS 6. Locked stack installed at SDK-compatible versions (NativeWind 4 + Tailwind 3, React Navigation 7, reanimated 4, gesture-handler, screens, safe-area-context, expo-secure-store, react-native-mmkv 4, expo-dev-client). Config in place: app.json (scheme castyou, bundle id com.castyou.app, new arch), babel/metro/tailwind/global.css/nativewind-env, eas.json (dev/preview/prod). Boot screen renders via NativeWind, imports @castyou/i18n (workspace resolution proven), and persists a launch counter through MMKV; storage + env seams stubbed (src/lib/storage.ts, src/lib/env.ts). Verified: expo-doctor 18/18; pnpm --filter @castyou/mobile typecheck green; full FE workspace typecheck (4/4)/test/audit still green (lockfile valid under both pnpm 9.12 CI + pnpm 11 local); root pnpm mobile:ios script (doctor → ios prebuild → run:ios, mobile-only). NOT runtime-verified — Dev Client build + simulator run is a local/device step. Gotcha fixed: React 19 (mobile) collided with React 18 (web) JSX types — pinned @types/react to 18.3.28 workspace-wide (mobile is fine on 18; expo.install.exclude keeps doctor happy) ([[project_castyou_react_native]]).

  • [x] RN-FOUND-001 — Scaffolded apps/mobile (Expo managed) in the pnpm/Turbo workspace; Metro resolves workspace packages (watchFolders + nodeModulesPaths + disableHierarchicalLookup); Dev Client configured.
  • [x] RN-FOUND-002 — NativeWind wired (babel preset jsxImportSource, nativewind/babel, metro withNativeWind, tailwind.config.js with a seed brand-token bridge, global.css, nativewind-env.d.ts). Full token port = RN-DS-001.
  • [x] RN-FOUND-003 — React Navigation wired (base bottom-tab navigator + NavigationContainer + gesture-handler/safe-area providers; TS/Metro/Babel). ESLint (eslint-config-expo) deferred.
  • [~] RN-FOUND-004 — Storage primitives created (expo-secure-store token adapter + MMKV kv in src/lib/storage.ts). Replacing the 12 localStorage sites happens in RN-1 (@castyou/core adapters).
  • [~] RN-FOUND-005 — Env seam (src/lib/env.ts, EXPO_PUBLIC_API_URL) + eas.json profiles in place. CI typecheck already covers mobile; EAS build-smoke job deferred.

Epic RN-1 — Shared Logic Extraction (@castyou/core)

Tier: Moderate · 5–7 sessions · Opus 4.8. Extract the platform-agnostic data/logic layer (~21k LOC) into a shared workspace package consumed by both web and mobile. Single highest-ROI move — write-once/run-both and prevents a web/mobile fork. Keep web CI green as the gate.

🟢 Proving slice landed 2026-06-28. packages/core (@castyou/core) created with the platform-agnostic data primitives behind an injected runtime: gqlClient, queryClient, queryKeys, errorBus + configureCore({ apiUrl, getToken, onAuthError }) (src/runtime.ts). The web wires its adapters in apps/app/src/lib/coreSetup.ts (token from auth store / impersonation, import.meta.env API URL, auth-error redirect) — imported first in main.tsx. The old lib/{graphqlClient,queryClient,queryKeys,errorBus}.ts are now thin re-exports from core, so all 244 import sites are untouched (@castyou/react-query stays a single instance via peer dep). Verified: full FE typecheck 5/5, app 603 + DS 49 tests pass, lockfile valid under pnpm 9.12 (CI) + 11. The pattern is proven; what remains is the bulk move (queries/hooks/stores) below.

  • [~] RN-CORE-001packages/core created; moved the genuinely-shared foundation: request/cache primitives (gqlClient, queryClient, queryKeys, errorBus), all 39 lib/queries modules (→ @castyou/core/queries/*, 115 imports codemod'd; BADGE_FIELDS/ApiBadge split out of lib/badges), and the auth store (createAuthStore factory).

    Decision (user, 2026-06-28): hooks move DEMAND-DRIVEN, not bulk. The original "move the bulk of the 85 hooks now" is superseded. Triage found ~71 are technically clean, but moving a feature hook before a mobile screen consumes it is speculative — the same smell as moving admin hooks. So: (1) admin/impersonation hooks (17: useAdmin*, useImpersonationSessions, useStartImpersonation, useMergeUserAccounts, useUserActivityLog, useVerificationRequests) NEVER move — mobile excludes admin. (2) The 54 mobile-relevant clean hooks move into @castyou/core/hooks/* one-by-one as the RN-4→RN-10 mobile screen that needs each one is built (each move then validated by a real second consumer, no rework on guesses). (3) The 13 platform-coupled hooks unblock as RN-2 (DS-native) / RN-CORE-004 (i18n) / RN-12 (flier) land. The shared data foundation above is the high-value part of RN-1 and is done.

  • [x] RN-CORE-002 — Done. Runtime seam (configureCore({apiUrl,getToken,onAuthError})) + the storage adapter (createAuthStore({storage, skipHydration, shouldPersist, onClear}) — web injects localStorage + impersonation rules, native will inject MMKV/SecureStore). Core peers react/@tanstack/react-query/zustand so they resolve to the consumer's versions (18 web / 19 native) — required to avoid a runtime React-dispatcher mismatch.
  • [ ] RN-CORE-003 — Move GraphQL transport (graphql-request) + subscriptions (graphql-ws/wsClient.ts); verify WS works under RN networking.
  • [ ] RN-CORE-004 — Move i18n core (i18n.ts); swap i18next-browser-languagedetector for an RN locale detector; keep @castyou/i18n strings shared.
  • [x] RN-CORE-005 — Web repointed at @castyou/core via re-exports + coreSetup.ts; web stays green (typecheck 5/5 + 603 app tests). Re-verify after each bulk move.

Epic RN-2 — Design System Native (@castyou/design-system-native)

Tier: Hard · 16–22 sessions · Opus → Fable. Rebuild all 54 DS components on native primitives (View/Text/Pressable/Image), mirroring the existing component API (same prop names/variants) so page migration is predictable. Largest single epic; Radix overlays have no RN equivalent and are reimplemented. Storybook → an in-app component gallery for visual QA.

🟢 EPIC COMPLETE 2026-06-29. @castyou/design-system-native rebuilt across all RN-DS-001…007. Components type className explicitly (src/primitives.ts) — the nativewind/types augmentation can't cross the pnpm boundary with the React 18/19 split; native-only package's react peer must be ^19.0.0 (else React 18 leaks in → dual-React + doctor fail). ~48 components (17 primitives + theme spine + 31 domain/overlay/data/media/atoms) all mirror the web API. Verified: workspace typecheck 5/5, expo-doctor 18/18, all instantiated with real props on the in-app GalleryScreen. On-device visual QA + media-capture wiring (RN-11) are the only follow-ups. ([[project_castyou_react_native]])

  • [x] RN-DS-001Done. Token scale (brand/neutral/secondary/violet/semantic, radius, type scale) in preset.js. Light/dark semantic system: surface-*/content-*/ds-border/ds-focus mapped to CSS variables in apps/mobile/global.css (:root + .dark, mirrored from web theme.css), darkMode:'class', theme-aware brand-400; ThemeProvider/useTheme delegate to NativeWind's color scheme. Gradients/blur: Gradient (expo-linear-gradient, brand presets) + BlurSurface (expo-blur). Poppins loaded via @expo-google-fonts/poppins in App.tsx, applied on the base Text. REMAINING (polish): single shared token source (still hand-mirrored web↔native); per-weight Poppins family mapping (weights currently faux on the regular family).
  • [x] RN-DS-002Done (17 primitives): Text, Button, Input, Textarea, Card, Badge, Chip, Avatar, Skeleton (+Text/Avatar), EmptyState, Logo, Switch, StatCard, Tabs, ProgressRing, StepIndicator, Pagination. react-native-svg@15.15.4 for ProgressRing.
  • [x] RN-DS-003Done. Domain cards + atoms: JobCard, TalentCard, PetCard, PostCard, GroupCard, SuggestionCard, SystemPostCard, JobFlierCard, JobSwipeCard, FollowButton, ReportButton, plus VerifiedTick, ProfileBadges, CasTarsCoin. Swipe gestures on the swipe cards are a follow-up (like/nope exposed via footer callbacks).
  • [x] RN-DS-004Done. Overlays on the RN Modal primitive (dimmed backdrop): Modal/Dialog, ConfirmDialog, Select, MultiSelect, FilterSheet (bottom-sheet pickers).
  • [x] RN-DS-005Done. Toast (context provider + useToast, animated stack), Tooltip (long-press popover), Menu (dropdown), LanguageSwitcher (controlled, no i18n coupling), ThemeToggle (uses useTheme).
  • [x] RN-DS-006Done. DataTable (generic), RangeSlider (@react-native-community/slider), SearchBar, GlitterBackground (on Gradient).
  • [x] RN-DS-007Done (shells). MediaGallery, MediaPlayer, VideoRecorder, ImageCropper (ref handle), FileUpload — UI + mirrored APIs; capture/playback/crop wiring deferred to RN-11 (marked with // RN-11: stubs). Also built the remaining atoms: PasswordStrengthMeter, SocialHandleInput, ExternalLink, FeatureGate, ErrorPage.

Epic RN-3 — Navigation & App Shell

Tier: Hard · 5–7 sessions · Opus 4.8. Re-model the 98-route react-router-dom tree (referenced in 135 files) as React Navigation stack/tab navigators; rebuild app shells + role guards as native containers. Opus designs the hierarchy + router-API codemod; Fable applies it across the 135 files.

  • [ ] RN-NAV-001 — Map route tree → navigator hierarchy (root stack, authenticated tab navigator, modal stack); document the mapping.
  • [ ] RN-NAV-002 — Rebuild AppShell.tsx + ProtectedShellLayout.tsx (auth/role/pet-owner/agency guards) as navigation guards + native tab bar.
  • [ ] RN-NAV-003 — Port DocumentTitleProvider/page-title behavior to native header titles (lib/pageTitles.ts).
  • [ ] RN-NAV-004 — Deep linking + universal/app links for handle routes (/talent/:handle, /producer/:handle, share links); codemod useNavigate/Link/useParams → React Navigation across 135 files.
  • [ ] RN-NAV-005 — Port ErrorBoundary.tsx + AccountBlockedPage.tsx (account-status gate).

Epic RN-4 — Auth & Onboarding

Tier: Moderate · 5–7 sessions · Opus → Fable. First real feature surface end-to-end (~1.7k LOC); validates core + DS-native + navigation before the high-volume epics. Expect extra iteration as the first full-stack integration.

  • [ ] RN-AUTH-001 — LoginPage, RegisterPage on DS-native; secure token storage via RN-FOUND-004.
  • [ ] RN-AUTH-002 — Social auth (socialAuth.ts) → native OAuth (expo-auth-session/Firebase Auth RN); 3 firebase web-SDK sites → @react-native-firebase. (Opus)
  • [ ] RN-AUTH-003 — OnboardingPage multi-step flow (1.1k LOC) on native StepIndicator.
  • [ ] RN-AUTH-004verify flow scaffolding (liveness deferred to RN-13).

Epic RN-5 — Feed & Social

Tier: Moderate · 6–8 sessions · Fable 5. Publication feed, feed tabs, social graph, post detail, owner post management, composer shells (~1.4k LOC). Mostly list/card UI over ported hooks; FlatList virtualization replaces web scroll.

  • [ ] RN-FEED-001 — Feed list + tabs + PostCard/SystemPostCard on DS-native (FlatList).
  • [ ] RN-FEED-002 — Post detail, likes/comments, owner actions (PostOwnerActionsModal), report content.
  • [ ] RN-FEED-003 — Composer & picker shells (ComposerPage, PickerPage) — wired to native capture in RN-11.
  • [ ] RN-FEED-004 — Social graph: follow, suggestions, unified search results, handles.

Epic RN-6 — Jobs

Tier: Moderate · 9–12 sessions · Fable 5. Largest feature area (~8k LOC): role-dispatched board, public job pages, create/edit (incl. pet jobs), match flow, invite-to-job, match breakdown. Big forms are the time sink — Opus defines one canonical native-form pattern, Fable replicates.

  • [ ] RN-JOBS-001 — JobsRouter + role-dispatched listing (talent match grid / producer table → native lists).
  • [ ] RN-JOBS-002 — Job detail (PublicJobPage, union resolver) + MatchBreakdown.
  • [ ] RN-JOBS-003 — Job create/edit + PetJob create/edit (large multi-section forms → native form components).
  • [ ] RN-JOBS-004 — Match/apply surface incl. portfolio/folder directory selection (now swipe-to-match per Epic 42; original JobApplyPage reference is stale).
  • [ ] RN-JOBS-005 — InviteToJobModal, shortlist/swipe actions (JobSwipeCard + gesture handling).
  • [ ] RN-JOBS-006 — Flier entry points link to RN-12.

Epic RN-7 — Profiles & Portfolio

Tier: Moderate · 7–9 sessions · Fable 5. Talent/producer/pet-owner profiles + edit pages, unified portfolio (MediaItem), folders, public share-link views (~6.5k LOC). DnD reorder is the one Hard sub-task — pull in Opus for the gesture pattern.

  • [ ] RN-PROF-001 — ProfilePage + TalentProfilePage / TalentEditPage (largest profile surface).
  • [ ] RN-PROF-002 — ProducerProfilePage / ProducerEditPage (handle links, structured portfolioLinks, open-roles).
  • [ ] RN-PROF-003 — PetOwner profile + pets list/detail/edit (image picker via RN-11).
  • [ ] RN-PROF-004 — Unified Portfolio (MediaItem grid, image/video/link, public/private) + Folders (single-membership, Uncategorized) with native gallery.
  • [ ] RN-PROF-005 — Portfolio drag-to-reorder (@dnd-kit → reanimated/gesture-handler). (Opus pattern)

Epic RN-8 — Discovery & Search

Tier: Moderate · 4–6 sessions · Fable 5. Discover feed (AI match), talent discovery, unified search. Reuses card/list/filter patterns from RN-5/6/7; swipe gesture is the only novel bit.

  • [ ] RN-DISC-001 — DiscoverPage (AI match feed) with swipe interaction (JobSwipeCard / gesture-handler).
  • [ ] RN-DISC-002 — TalentDiscoveryPage grid + filters (FilterSheet → bottom sheet).
  • [ ] RN-DISC-003 — Unified SearchPage (tabs, results) + native SearchBar.

Epic RN-9 — Messaging & Notifications (+ Push)

Tier: Hard · 5–7 sessions · Opus → Fable. Real-time messaging (GraphQL subscriptions over WS), notifications center, and net-new native push. Opus for WS-over-RN reliability + push infra; Fable for the list UIs. Push is the schedule risk (backend coordination).

  • [ ] RN-MSG-001 — Conversation list + thread UI on native; verify graphql-ws subscriptions over RN networking + reconnect/background behavior.
  • [ ] RN-MSG-002 — Per-conversation + nav-badge unread state (no message notifications, per [[Notifications vs Messages]]).
  • [ ] RN-NOTIF-001 — Notifications center + NotificationBell → native badge.
  • [ ] RN-PUSH-001Native push (Expo Notifications / FCM+APNs): device-token registration, backend hook, deep-link-on-tap. (Net-new; current notifications are in-app only — coordinate with backend.)

Epic RN-10 — Groups, Agency, CasTars, Bounty, Settings & Misc

Tier: Moderate · 7–9 sessions · Fable 5. Remaining smaller areas batched (~4.5k LOC): all standard list/form/card UI over ported hooks — batch aggressively.

  • [ ] RN-MISC-001 — Groups (list, detail, activity feed, events, group apply).
  • [ ] RN-MISC-002 — CasTars (wallet/ledger, CaStarsWidget) + Bounty (list, create, detail) + UpgradeModal.
  • [ ] RN-MISC-003 — Agency tier pages.
  • [ ] RN-MISC-004 — Settings, Pricing, Support, ReportBugModal.
  • [ ] RN-MISC-005 — Impersonation banner (non-admin user-facing portion only) + account-status enforcement surfaces.

Epic RN-11 — Media Capture & Processing

Tier: Hard · 6–8 sessions · Opus 4.8. Replace every browser media API with native modules. Foundational — do it before the features that consume it (composer, profile/pet edits, DS media components). Permissions + iOS/Android quirks require real-device testing.

  • [ ] RN-MEDIA-001 — Camera + photo/video capture (react-native-vision-camera/expo-camera) replacing getUserMedia/MediaRecorder.
  • [ ] RN-MEDIA-002 — Image picker + cropper (replace web ImageCropper) and document/file upload (replace <input type=file>).
  • [ ] RN-MEDIA-003 — Video thumbnail generation (generateVideoThumbnail.ts) + post-image baking (bakePostImage.ts) — canvas → Skia/native.
  • [ ] RN-MEDIA-004 — Wire S3 presigned-URL upload to native file refs; createObjectURL → native URIs.
  • [ ] RN-MEDIA-005 — DS MediaPlayer/MediaGallery/VideoRecorder native impls (expo-av/video).

Epic RN-12 — Flier / Poster Editor (Skia)

Tier: Research · 7–11 sessions · Opus 4.8. Rebuild the konva/react-konva flier editor on @shopify/react-native-skia — a from-scratch reimplementation of a complex interactive canvas. Highest-uncertainty epic; consider a read-only viewer for v1 if schedule-constrained.

  • [ ] RN-FLIER-001 — Spike Skia: reproduce layer model from FlierCanvas.tsx + renderFlier.ts (text/image/gradient layers; flierCanvasDefaults.ts).
  • [ ] RN-FLIER-002 — Interactive editing: drag/scale/select layers via gesture-handler + reanimated.
  • [ ] RN-FLIER-003 — AI layer prompt input (FlierAIPromptInput) + render-to-image export (Skia snapshot → upload).
  • [ ] RN-FLIER-004 — Parity pass against web output (FlierThumbnail, JobFlierCard previews).

Epic RN-13 — Face Liveness Verification

Tier: Research · 5–8 sessions · Opus 4.8. Rebuild identity liveness (@mediapipe/tasks-vision WASM) on native camera + on-device face detection (vision-camera frame processors + ML Kit). Depends on RN-11; security-sensitive — over-budget review, device testing mandatory.

  • [ ] RN-LIVE-001 — Spike vision-camera frame processor + ML Kit face detection; confirm landmark/challenge signal on both platforms.
  • [ ] RN-LIVE-002 — Port challenge logic (blink/turn prompts) + pass/fail thresholds from LivenessChallenge.tsx.
  • [ ] RN-LIVE-003 — Wire into the verify flow (RN-AUTH-004) + backend verification submission.
  • [ ] RN-LIVE-004 — On-device performance + anti-spoofing review.

Epic RN-14 — Export & PDF

Tier: Moderate · 2–3 sessions · Opus → Fable. Replace jspdf pitch/sheet export. Server-side generation is likely the cleaner long-term answer (reduces this to share-sheet wiring).

  • [ ] RN-EXPORT-001 — Decide RN-side PDF lib vs server-side generation for ExportPitchModal.
  • [ ] RN-EXPORT-002 — Implement chosen path + native share-sheet for the resulting file.

Epic RN-15 — Release Engineering

Tier: Hard · 4–6 sessions · Opus 4.8. Everything to ship to stores. Much of the wall-clock is store review + account setup (human-only); Claude's share is config + reporting integration.

  • [ ] RN-REL-001 — EAS build/submit profiles (dev/preview/prod), code signing (certs/provisioning), app icons & splash.
  • [ ] RN-REL-002 — Crash/error reporting RN SDK (mirror web error bus → native).
  • [ ] RN-REL-003 — OTA update channel (EAS Update) + version/rollback policy.
  • [ ] RN-REL-004 — Store listings, privacy disclosures (camera/photos/push), review submission.
  • [ ] RN-REL-005 — End-to-end deep-link/universal-link verification on device.

Last updated: 2026-06-28. Update ticket checkboxes as features are implemented. React Native Migration track (Epics RN-0 … RN-15) added 2026-06-28, mirrored from CASTYOU-REACT-NATIVE-MIGRATION.md — that doc remains the source of truth for per-ticket file lists and approach.