Feature-Sliced Design (FSD) organizes front-end code into layers and slices with strict import rules. On Expo, map FSD to app/, features/, entities/, and shared/ - you get the boundary benefits without seven top-level folders on day one.
shared ← imported by everyone
↑
entities ← features may import entities; entities never import features
↑
features ← no cross-feature imports; use entities or app-layer orchestration
↑
app ← wires providers; routes import feature public APIs
Putting feature logic in Expo app/ routes - Routes become god files. Fix: Re-export from @/features/*; parse params only.
Cross-feature imports for "just one component" - Graph becomes cyclic within two sprints. Fix: Move shared UI to entities/ or shared/ui; orchestrate in the route.
Empty index.ts barrels exporting everything - Accidental public API bloat. Fix: Export deliberately; treat index.ts like a package manifest.
Creating entities/ for every DTO - Not every API response is a domain entity. Fix: Map DTOs in api/; promote to entity when two features need the type.
Skipping ESLint enforcement - FSD without lint rules is folder theater. Fix: Add no-restricted-imports before feature count hits double digits.
Duplicating shared/ui and entities/*/ui - Unclear ownership. Fix: Entity UI displays one noun (UserAvatar); shared UI is generic (Button).
Monolithic features/orders/model/store.ts - Becomes a god module. Fix: Split by segment; one hook per screen orchestration.
No. Most Expo apps use app (providers), features, entities, and shared. Skip pages (Expo Router replaces it) and widgets until a composite block repeats across routes.
Where does Expo Router's app/ folder fit?
Expo app/ is the routing shell - file-based routes and layouts. FSD src/app/ holds global providers and bootstrap. Keep route files thin; product code lives in src/features/.
Can features import other features?
No - FSD forbids slice-to-slice imports at the same layer. Share through entities, shared, or orchestrate at the route / src/app layer.
What is a segment?
A subfolder inside a slice: ui, model, api, lib. Segments group files by technical role without creating new top-level layers.
Should I use @x public API notation?
Optional. The @x cross-export pattern from web FSD is less common in RN. A plain index.ts barrel per slice is sufficient.
Where do Zustand stores live?
In features/<name>/model/ for feature-local state. Global session state may live in src/app/providers/ or features/session/model/ depending on scope.
How does FSD work with TanStack Query?
Query hooks belong in features/<name>/model/ or entities/<name>/api/. Entity-level queries (useUser) serve multiple features; feature-level queries (useCheckout) stay in the feature.
What goes in shared/ui vs entities/user/ui?
shared/ui/Button is generic. entities/user/ui/UserAvatar knows about User - it displays domain data and may be reused by many features.
Can I mix FSD with a monorepo?
Yes. Packages typically hold shared and entities; the Expo app holds features and routes. See shared-packages Metro guide for workspace resolution.
How do I migrate from flat folders to FSD?
One feature per PR: move screens/OrdersScreen.tsx → features/orders/ui/, add index.ts, update imports. Enable ESLint rules after the second migrated feature.
Is app/_layout.tsx part of FSD app layer?
Yes - root layout wraps providers and navigation chrome. Register AppProviders from src/app/providers/ in app/_layout.tsx, not business logic.
When is a widget not a feature?
When it has no standalone user story - e.g. a StatsCard reused on home and dashboard. Features deliver user value ("place order"); widgets compose entities for layout.
Does FSD replace Clean Architecture?
They complement each other. FSD organizes file structure; Clean Architecture organizes dependency direction inside a feature (use cases, adapters). Use both when complexity warrants it.
How many features is too many?
There is no hard cap - slices should match product domains. If features/misc appears, split by user journey or merge into an existing slice.