Clean Architecture separates what the app does (entities, use cases) from how it talks to the world (adapters). On React Native, that means testable use cases in TypeScript - not abstract factories for every button press.
Hooks that call fetch directly - Bypasses use cases; tests need MSW for every screen. Fix: Move IO to adapters; hooks call use cases.
Entities importing adapters - Inverts dependency rule. Fix: Adapters import entity types; use cases depend on port interfaces.
God domain/ shared across all features - Becomes a monolith. Fix: Per-feature domain/ unless entity is truly global (User → entities/user).
TanStack Query inside use cases - Query is a presentation-cache concern. Fix: Use case returns data; hook or repository adapter feeds the query client.
Full ceremony is overkill for small apps. Adopt entities + use cases + adapters for features with real business rules (auth, payments, offline sync). CRUD lists can stay hook + API module.
Where do use cases live?
Inside the feature: src/features/auth/domain/use-cases/. Cross-feature rules belong in src/entities/<name>/ or a shared domain package.
Do I need interfaces for every adapter?
Add a port interface when you have two implementations (live API + mock, or REST + GraphQL). A single adapter can use a concrete type until the second implementation exists.
How does this work with Expo Router?
Routes stay thin. SignInScreen receives onSignedIn from the route; navigation is an outer layer concern - not inside the use case.
Should use cases return entities or DTOs?
Return entities or feature-specific result types. Map API DTOs to entities inside adapters - DTO shapes never leak to UI.
Can use cases call other use cases?
Yes, compose them - checkout may call validateCoupon and reserveInventory. Keep composition in a parent use case, not in UI.
Where does Zustand fit?
Zustand holds client UI state or a session cache updated by use-case results. Do not put fetch logic inside store actions - call use cases from actions instead.
How do I test signIn without a device?
Pass fake AuthGateway and TokenStorage objects to signIn(). Assert on the discriminated union - no renderer required.
What about offline-first sync?
Model SyncQueue as a port. Use case enqueueMutation writes to queue adapter; background worker adapter drains queue - UI calls use cases, not SQLite directly.
Is Redux a clean architecture layer?
Redux is infrastructure/presentation state. Use cases should not dispatch Redux actions - hooks dispatch after use cases succeed.
How is this different from FSD?
FSD is folder taxonomy. Clean Architecture is dependency direction inside those folders. Use FSD segments (domain/, adapters/) to host clean rings.
When should I extract entities to src/entities/?
When two or more features import the same noun (User, Order). Feature-local entities stay in features/<name>/domain/ until shared.
Do I need Dagger/Hilt-style DI?
No. Plain factory functions and React context are sufficient - see Dependency Injection in RN.
How many lines before a hook becomes a use case?
Line count is a weak signal. Extract when the hook mixes IO + branching business rules + UI state and tests require mounting React - typically 40+ lines of orchestration.