feature-driven-architecture

🧭 Feature-Driven Architecture (FDA) β€” Overview

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.


🎯 What Is Feature-Driven Architecture?

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.


🧩 Core Principles

  1. Feature encapsulation β€” Each feature manages its own logic, types, and UI.
  2. Plug-and-play β€” Features can be added, removed, or migrated without breaking the app.
  3. Independence β€” No direct dependencies between features; share only through shared/.
  4. Consistency β€” Shared naming conventions and structure across all features.
  5. Scalability β€” Works seamlessly from small apps to multi-team monorepos.

πŸ—‚οΈ Global Directory Structure

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

🧱 Feature Structure

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

πŸ”— App Router Integration

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";

🧠 Shared Logic

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

✍️ Naming Conventions

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

πŸš€ Workflow for New Features

  1. Create a folder under src/feature/<feature>.
  2. Add only the needed layers:

    • lib/ β†’ server actions & logic
    • queries/, options/ β†’ React Query setup
    • stores/ β†’ Zustand state
    • schemas/ β†’ Zod validation
    • components/ β†’ UI layer
  3. Expose APIs via re-exports in /app/api/....
  4. Keep cross-feature logic in src/shared only.

βš™οΈ Core Design Patterns


πŸ’‘ Example: User Feature

src/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

🧩 Why FDA Works

Feature-Driven Architecture makes scaling easier because:


Let’s build scalable apps β€” one feature at a time. πŸš€