Feature-Sliced Design Architecture
Overview
Provides guidance for implementing Feature-Sliced Design (FSD v2.1) in Next.js applications. FSD organizes code into a layered hierarchy that prevents circular dependencies and promotes maintainability.
Next.js Customization (Only Difference from Official FSD)
This skill adapts FSD for Next.js App Router with one structural choice:
| Official FSD | This Skill (Next.js) |
|---|---|
app/ (routing, providers) + pages/ (page logic) | src/app/ = Next.js routing + FSD App merged |
pages/ layer | src/views/ — page business logic |
| Separate routing layer | Next.js file-based routing (page.tsx, layout.tsx) |
src/app/ holds both Next.js routing files (layout.tsx, page.tsx, route groups) and FSD App layer concerns (providers, styles). page.tsx imports from @/views and renders. All other FSD rules (layers, slices, segments, public API, import rules) align with FSD v2.1.
Reference files (load as needed):
- •layers-and-segments.md — Layer definitions, slices (zero coupling, slice groups), segment patterns, migration
- •public-api.md — Public API rules, @x cross-imports, shared/ui structure, circular imports
- •code-smells.md — Desegmentation, generic folders anti-patterns
- •examples.md — Full examples: layers, auth patterns, types, API requests
- •react-query.md — React Query + FSD: Query Factory, pagination, QueryProvider
- •monorepo.md — (Optional) Turborepo + FSD structure
Purpose
Feature-Sliced Design (FSD) is an architectural methodology for organizing frontend applications into a standardized, scalable structure. It provides clear separation of concerns through a layered hierarchy that prevents circular dependencies and promotes maintainability.
Why use FSD
- •Scalability: Grows naturally as your application expands
- •Maintainability: Clear boundaries make refactoring safer
- •Team collaboration: Consistent structure enables parallel development
- •Onboarding: New developers understand architecture quickly
Unified src/app/ structure
Both Next.js App Router and FSD App layer live in src/app/. Next.js recognizes layout.tsx, page.tsx, etc. inside src/app/, so all code stays under src/ without a root-level app/ folder, aligning with FSD v2.1.
Custom 'views' layer
This skill uses 'views' instead of the standard FSD 'pages' layer. Page business logic goes in /src/views; routing structure stays in /src/app/.
When to Use
Apply Feature-Sliced Design when:
- •Starting new Next.js projects that require clear architectural boundaries
- •Refactoring growing codebases that lack consistent structure
- •Working with multi-developer teams needing standardized organization
- •Building applications with complex business logic requiring separation of concerns
- •Scaling applications where circular dependencies become problematic
- •Creating enterprise applications with long-term maintenance requirements
- •(Optional) Developing monorepo applications (Turborepo, etc.) — see monorepo.md
Core Principles (FSD v2.1)
Layer Hierarchy
FSD v2.1 organizes code into 7 layers (from most to least responsibility/dependency):
- •app - App-wide matters (entrypoint, providers, global styles, router config)
- •processes - Deprecated; move contents to
featuresandapp - •views - Page-level business logic (custom naming; standard FSD uses 'pages')
- •widgets - Large self-sufficient UI blocks
- •features - Main user interactions and business value
- •entities - Business domain objects and models
- •shared - Foundation (UI kit, API client, libs, config)
You don't have to use every layer — add only what brings value. Most projects use at least Shared, Pages (or views), and App.
FSD v2.1 pages-first: Start with pages/views; keep most logic there. Extract to features/entities only when code is reused across several pages.
Import rule: A module can only import from layers strictly below it.
┌─────────────────┐ │ app │ ← Can import from all layers below ├─────────────────┤ │ views │ ← Can import: widgets, features, entities, shared ├─────────────────┤ │ widgets │ ← Can import: features, entities, shared ├─────────────────┤ │ features │ ← Can import: entities, shared ├─────────────────┤ │ entities │ ← Can import: shared only ├─────────────────┤ │ shared │ ← Cannot import from any FSD layer └─────────────────┘
'Views' vs 'Pages' Layer
- •
src/app/: Next.js routing + FSD App layer —layout.tsx,page.tsx, route groups, providers, styles.page.tsximports from@/viewsand renders. - •
src/views/: Page business logic, component composition — View components, models, API calls. Composes widgets, features, entities.
Slices and Public API
Slices are domain-based partitions within layers (except app and shared). Examples: views/dashboard, widgets/header, features/auth, entities/user.
- •Zero coupling, high cohesion — Slices should be independent (no same-layer imports) and contain related code.
- •Slice groups — Related slices can live in a folder, but no code sharing between them inside that folder.
- •Each slice exports through
index.ts. Use explicit exports — avoidexport * from. Consumers import from public API only.
See public-api.md for circular import rules, shared/ui structure, and @x cross-imports.
Segments
Segments group code by purpose (why), not essence (what). Avoid components, hooks, types, utils — use purpose-based names.
- •ui/ - React components, visual elements
- •model/ - Business logic, state management, TypeScript types
- •api/ - API clients, data fetching, external integrations
- •lib/ - One area of focus per library; document in README
- •config/ - Configuration constants, feature flags
Shared layer segments: api, ui, lib, config, i18n, routes
Naming Conventions
| Target | Convention | Example |
|---|---|---|
| Folders, slices | kebab-case | user-profile/, theme-toggle/ |
| Component files | kebab-case | login-form.tsx, user-card.tsx |
| Hook files | camelCase | useAuth.ts, useDashboard.ts |
| Store files | camelCase | authStore.ts |
| Function/API collections | camelCase | userApi.ts, formatDate.ts |
FSD with Next.js App Router
Next.js recognizes routing files inside src/app/. All FSD layers live under src/; no root-level app/ folder.
File organization:
my-nextjs-app/ ├── src/ │ ├── app/ # Next.js routing + FSD App layer │ │ ├── layout.tsx │ │ ├── page.tsx │ │ ├── dashboard/page.tsx │ │ ├── providers/ │ │ └── styles/ │ ├── views/ │ ├── widgets/ │ ├── features/ │ ├── entities/ │ └── shared/ │ ├── ui/ │ ├── lib/ │ └── api/ └── package.json
Routing pages import from views:
// src/app/dashboard/page.tsx
import { DashboardView } from '@/views/dashboard';
export default function DashboardPage() {
return <DashboardView />;
}
(Optional) Monorepo: See monorepo.md
For full directory structure and layer examples, see references.
Workflow
Step 1: Set Up Layer Directories
mkdir -p src/{app,views,widgets,features,entities,shared}
mkdir -p src/app/{providers,styles,config}
mkdir -p src/shared/{ui,lib,api,config}
Step 2: Create First Entity
Start with entities (bottom layer). Define core business models in entities/{name}/model/ and API in entities/{name}/api/. Export via index.ts.
Step 3: Build Features Using Entities
Create features in features/{name}/. Features import from entities and shared only.
Step 4: Compose Widgets from Features
Build composite widgets in widgets/{name}/. Widgets can import from features, entities, shared.
Step 5: Assemble Views
Create page-level views in views/{name}/. Views compose widgets, features, entities.
Step 6: Connect to App Router
Wire views to Next.js routing. page.tsx imports from @/views/{slice}.
Import Rules
Allowed
- •Layer importing from layer below
- •Any layer importing from shared
- •Slice importing different slice in lower layer
Forbidden
- •Layer importing from same or higher layer
- •Cross-slice imports within same layer
- •Shared importing from FSD layers
Fixing Circular Dependencies
- •Extract shared logic to lower layer (entities or shared)
- •Create higher layer (widget) that imports both
- •Review if slice should be split
Public API Enforcement
Always use index.ts to control exports. Import from public API only:
// ✅ Correct
import { LoginForm } from '@/features/auth';
// ❌ Wrong (deep import)
import { LoginForm } from '@/features/auth/ui/LoginForm';
Migration Strategy (Bottom-up)
- •Start with shared layer — extract UI, lib, API client
- •Define entities — business domain objects
- •Extract features — user interactions
- •Build widgets — composite UI blocks
- •Organize views — move page logic from page files
- •Configure app layer — providers, styles
Migrate incrementally; run tests after each layer.
Best Practices
- •No cross-slice imports within same layer
- •Export through
index.ts; avoidexport * from; use explicit exports - •shared/ui: per-component index for tree-shaking (see public-api.md)
- •Avoid generic folders/files:
types.ts,utils.ts,components/— use domain names (see code-smells.md) - •Colocate tests next to implementation
- •Keep slices focused; avoid "god slices"
- •Name by domain:
features/product-searchnotfeatures/search-bar-component - •Use TypeScript strict mode
Troubleshooting
Import path issues: Configure path aliases in tsconfig.json — see Configuration below.
Build errors: Clear .next, run npm install, restart dev server.
Configuration
TypeScript Path Aliases
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": ["src/app/*"],
"@/views/*": ["src/views/*"],
"@/widgets/*": ["src/widgets/*"],
"@/features/*": ["src/features/*"],
"@/entities/*": ["src/entities/*"],
"@/shared/*": ["src/shared/*"]
}
},
"include": ["src"]
}
ESLint (Optional)
'no-restricted-imports': ['error', {
patterns: [{
group: ['@/views/*', '@/widgets/*'],
message: 'Features cannot import from views or widgets',
}],
}]
Reference Files
Documentation Library
Load these resources as needed during development:
Core FSD Reference
- •layers-and-segments.md — Layers, slices (zero coupling, slice groups), segments, @x cross-reference, migration (including v2.0→v2.1)
- •public-api.md — Public API rules, @x cross-imports, circular imports, shared/ui tree-shaking, Steiger
- •code-smells.md — Desegmentation, generic folder/file anti-patterns
Implementation Examples
- •examples.md — Full examples: each layer, page layouts, auth, types/DTOs, API requests, domain-based files
Optional
- •react-query.md — React Query + FSD: Query Factory, pagination, QueryProvider
- •monorepo.md — Turborepo + FSD structure
External