Feature-Driven Architecture (FDA) is a modular and scalable way to structure modern web applications, designed to reduce complexity in large React/Next.js codebases. Instead of organizing files by type (components, hooks, utils, etc.), FDA organizes by feature, creating self-contained, reusable modules.
Traditional folder-by-type architectures often lead to fragmentation β you end up navigating between multiple folders just to work on a single feature. FDA solves this by grouping everything related to a specific feature (UI, logic, state, API) into one cohesive unit.
Each feature owns its own domain logic, minimizing coupling and making refactoring safer and faster.
In short: each feature is a mini-application that can live, evolve, and be maintained independently.
shared/.your-project/
βββ src/
β βββ app/ β Next.js App Router (public & admin routes)
β βββ feature/ β Core feature modules
β βββ shared/ β Cross-feature utilities, UI, hooks
β βββ providers/ β React context providers
β βββ styles/ β Global styles & design tokens
β βββ types/ β Global shared TypeScript types
βββ public/ β Static assets
βββ tests/ β Integration & e2e tests
βββ config/ β Environment & build configuration
Each feature is self-contained, following the same internal layout:
src/feature/<feature-name>/
βββ api/ β Next.js API handlers or client utilities
β βββ api<Feature>.ts β Main feature API entry (re-exported in /app/api)
β βββ client/ β Optional: feature-specific API client
βββ components/ β UI components specific to this feature
βββ hooks/ β React hooks for this feature
βββ lib/ β Server actions or internal logic
βββ queries/ β React Query hooks
βββ options/ β Query configuration
βββ schemas/ β Zod validation schemas
βββ stores/ β Zustand state management
βββ types/ β Feature-specific types
βββ index.ts β Central export for the feature API & hooks
API handlers are re-exported from their feature modules into the Next.js app/api layer:
// src/app/api/admin/user/route.ts
export { GET, POST } from "@/feature/user/api/apiUser";
UI routes can directly consume hooks, queries, and components from the same feature:
// src/app/admin/user/page.tsx
import { useUsers } from "@/feature/user/queries/useUsers";
import { UserTable } from "@/feature/user/components/UserTable";
| Folder | Purpose |
|---|---|
src/shared/ui/ |
Design system & UI primitives (buttons, modals, etc.) |
src/shared/lib/ |
Utilities, helpers, constants, config functions |
src/shared/hooks/ |
Generic reusable React hooks |
src/shared/types/ |
Global shared types & interfaces |
| Type | Convention | Example |
|---|---|---|
| React Query hook | use prefix |
useUserList.ts |
| Zustand store | Store suffix |
userStore.ts |
| Zod schema | Schema suffix |
userSchema.ts |
| API handler | api prefix |
apiUser.ts |
| Component | PascalCase | UserTable.tsx |
src/feature/<feature>.Add only the needed layers:
lib/ β server actions & logicqueries/, options/ β React Query setupstores/ β Zustand stateschemas/ β Zod validationcomponents/ β UI layer/app/api/....src/shared only.lib/api/, re-exported in app/api/queries/ + options/ via React Querystores/ via Zustandschemas/ via Zodtypes/ via TypeScriptsrc/feature/user/
βββ api/
β βββ apiUser.ts
βββ components/
β βββ UserTable.tsx
βββ lib/
β βββ userActions.ts
βββ queries/
β βββ useUsers.ts
βββ stores/
β βββ userStore.ts
βββ schemas/
β βββ userSchema.ts
βββ types/
β βββ userTypes.ts
βββ index.ts
Feature-Driven Architecture makes scaling easier because:
Letβs build scalable apps β one feature at a time. π