feature-sliced-design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Feature-Sliced Design Architecture

Feature-Sliced Design 架构

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应用中实现Feature-Sliced Design(FSD v2.1)的指导方案。FSD通过分层结构组织代码,可避免循环依赖并提升可维护性。

Next.js Customization (Only Difference from Official FSD)

Next.js 定制适配(与官方FSD的唯一区别)

This skill adapts FSD for Next.js App Router with one structural choice:
Official FSDThis 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 layerNext.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

本方案针对Next.js App Router对FSD进行了适配,主要结构差异如下:
官方FSD本方案(适配Next.js)
app/
(路由、提供者) +
pages/
(页面逻辑)
src/app/
= Next.js路由 + FSD App层合并
pages/
src/views/
— 页面业务逻辑
独立的路由层Next.js 基于文件的路由(
page.tsx
,
layout.tsx
src/app/
同时承载Next.js路由文件(
layout.tsx
,
page.tsx
, 路由组)和FSD App层相关内容(提供者、样式)。
page.tsx
@/views
导入并渲染组件。其余所有FSD规则(分层、切片、分段、公共API、导入规则)均与FSD v2.1保持一致。
参考文件(按需查阅):
  • layers-and-segments.md — 分层定义、切片(零耦合、切片组)、分段模式、迁移指南
  • public-api.md — 公共API规则、@x跨模块导入、shared/ui结构、循环依赖处理
  • code-smells.md — 反模式示例:分段缺失、通用文件夹滥用
  • examples.md — 完整示例:分层结构、鉴权模式、类型定义、API请求
  • react-query.md — React Query + FSD:查询工厂、分页、QueryProvider配置
  • monorepo.md — (可选)Turborepo + FSD 结构方案

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.
Feature-Sliced Design(FSD)是一种前端应用架构方法论,通过标准化的可扩展结构组织代码。它通过分层结构清晰划分职责,避免循环依赖并提升可维护性。

Why use FSD

为何选择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

统一的
src/app/
结构

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.
Next.js App Router和FSD App层均位于**
src/app/
**目录下。Next.js可识别
src/app/
内的
layout.tsx
page.tsx
等文件,因此所有代码都在
src/
目录下,无需根目录级别的
app/
文件夹,与FSD v2.1规范对齐。

Custom 'views' layer

自定义的'views'层

This skill uses 'views' instead of the standard FSD 'pages' layer. Page business logic goes in
/src/views
; routing structure stays in
/src/app/
.
本方案使用'views'层替代标准FSD的'pages'层。页面业务逻辑存放于
/src/views
;路由结构保留在
/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
在以下场景中应用Feature-Sliced Design:
  • 启动需要清晰架构边界的全新Next.js项目
  • 重构缺乏统一结构的大型代码库
  • 多开发者团队协作,需要标准化的代码组织方式
  • 构建业务逻辑复杂、需要职责分离的应用
  • 解决循环依赖问题的规模化应用
  • 构建需要长期维护的企业级应用
  • (可选)开发monorepo应用(Turborepo等)——详见monorepo.md

Core Principles (FSD v2.1)

核心原则(FSD v2.1)

Layer Hierarchy

分层结构

FSD v2.1 organizes code into 7 layers (from most to least responsibility/dependency):
  1. app - App-wide matters (entrypoint, providers, global styles, router config)
  2. processes - Deprecated; move contents to
    features
    and
    app
  3. views - Page-level business logic (custom naming; standard FSD uses 'pages')
  4. widgets - Large self-sufficient UI blocks
  5. features - Main user interactions and business value
  6. entities - Business domain objects and models
  7. 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
└─────────────────┘
FSD v2.1将代码分为7层(按职责/依赖程度从高到低排序):
  1. app - 应用全局内容(入口、提供者、全局样式、路由配置)
  2. processes - 已废弃;将内容迁移至
    features
    app
  3. views - 页面级业务逻辑(自定义命名;标准FSD使用'pages')
  4. widgets - 大型独立UI块
  5. features - 核心用户交互与业务价值模块
  6. entities - 业务领域对象与模型
  7. shared - 基础层(UI组件库、API客户端、工具库、配置)
无需使用所有分层——仅添加能带来实际价值的层。大多数项目至少会使用Shared、Pages(或views)和App层。
FSD v2.1 以页面/视图优先:从页面/视图开始构建,将大部分逻辑保留在该层。仅当代码需要在多个页面复用时,再提取至features/entities层。
导入规则:模块仅能从严格下层的模块导入。
┌─────────────────┐
│      app        │  ← 可导入所有下层模块
├─────────────────┤
│     views       │  ← 可导入:widgets、features、entities、shared
├─────────────────┤
│    widgets      │  ← 可导入:features、entities、shared
├─────────────────┤
│    features     │  ← 可导入:entities、shared
├─────────────────┤
│    entities     │  ← 仅可导入:shared
├─────────────────┤
│     shared      │  ← 不可导入任何FSD分层模块
└─────────────────┘

'Views' vs 'Pages' Layer

'Views'层 vs 'Pages'层

  • src/app/
    : Next.js routing + FSD App layer —
    layout.tsx
    ,
    page.tsx
    , route groups, providers, styles.
    page.tsx
    imports from
    @/views
    and renders.
  • src/views/
    : Page business logic, component composition — View components, models, API calls. Composes widgets, features, entities.
  • src/app/
    :Next.js路由 + FSD App层 — 包含
    layout.tsx
    page.tsx
    、路由组、提供者、样式。
    page.tsx
    @/views
    导入并渲染组件。
  • src/views/
    :页面业务逻辑、组件组合 — 视图组件、模型、API调用。组合widgets、features、entities模块。

Slices and Public API

切片与公共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 — avoid
    export * from
    . Consumers import from public API only.
See public-api.md for circular import rules, shared/ui structure, and @x cross-imports.
切片是分层内基于领域的分区(app和shared层除外)。示例:
views/dashboard
widgets/header
features/auth
entities/user
  • 零耦合、高内聚 — 切片应保持独立(同层内禁止跨切片导入),且包含相关联的代码。
  • 切片组 — 相关切片可存放在同一文件夹下,但文件夹内的切片之间禁止共享代码
  • 每个切片通过
    index.ts
    导出内容。使用显式导出——避免
    export * from
    语法。消费者仅能从公共API导入内容。
关于循环导入规则、shared/ui结构、@x跨模块导入的详细说明,请查阅public-api.md

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
分段按**用途(why)**而非本质(what)对代码进行分组。避免使用
components
hooks
types
utils
这类通用命名——使用基于用途的命名。
  • ui/ - React组件、视觉元素
  • model/ - 业务逻辑、状态管理、TypeScript类型
  • api/ - API客户端、数据获取、外部集成
  • lib/ - 每个文件聚焦一个工具库;在README中说明用途
  • config/ - 配置常量、功能开关
Shared层的分段
api
ui
lib
config
i18n
routes

Naming Conventions

命名规范

TargetConventionExample
Folders, sliceskebab-case
user-profile/
,
theme-toggle/
Component fileskebab-case
login-form.tsx
,
user-card.tsx
Hook filescamelCase
useAuth.ts
,
useDashboard.ts
Store filescamelCase
authStore.ts
Function/API collectionscamelCase
userApi.ts
,
formatDate.ts
目标规范示例
文件夹、切片kebab-case
user-profile/
theme-toggle/
组件文件kebab-case
login-form.tsx
user-card.tsx
Hook文件camelCase
useAuth.ts
useDashboard.ts
状态管理文件camelCase
authStore.ts
函数/API集合camelCase
userApi.ts
formatDate.ts

FSD with Next.js App Router

FSD 与 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:
typescript
// 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.
Next.js可识别
src/app/
内的路由文件。所有FSD分层均位于
src/
目录下;无根目录级别的
app/
文件夹
文件组织结构:
my-nextjs-app/
├── src/
│   ├── app/                    # Next.js路由 + FSD App层
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   ├── dashboard/page.tsx
│   │   ├── providers/
│   │   └── styles/
│   ├── views/
│   ├── widgets/
│   ├── features/
│   ├── entities/
│   └── shared/
│       ├── ui/
│       ├── lib/
│       └── api/
└── package.json
路由页面从views层导入组件:
typescript
// src/app/dashboard/page.tsx
import { DashboardView } from '@/views/dashboard';
export default function DashboardPage() {
  return <DashboardView />;
}
(可选)Monorepo方案:详见monorepo.md
完整的目录结构和分层示例,请查阅references

Workflow

实施流程

Step 1: Set Up Layer Directories

步骤1:创建分层目录

bash
mkdir -p src/{app,views,widgets,features,entities,shared}
mkdir -p src/app/{providers,styles,config}
mkdir -p src/shared/{ui,lib,api,config}
bash
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

步骤2:创建第一个Entity

Start with entities (bottom layer). Define core business models in
entities/{name}/model/
and API in
entities/{name}/api/
. Export via
index.ts
.
从最底层的entities层开始。在
entities/{name}/model/
中定义核心业务模型,在
entities/{name}/api/
中定义相关API。通过
index.ts
导出内容。

Step 3: Build Features Using Entities

步骤3:基于Entity构建Feature

Create features in
features/{name}/
. Features import from entities and shared only.
features/{name}/
中创建功能模块。Features层仅可从entities和shared层导入内容。

Step 4: Compose Widgets from Features

步骤4:基于Feature构建Widget

Build composite widgets in
widgets/{name}/
. Widgets can import from features, entities, shared.
widgets/{name}/
中创建复合UI块。Widgets层可从features、entities、shared层导入内容。

Step 5: Assemble Views

步骤5:组装View

Create page-level views in
views/{name}/
. Views compose widgets, features, entities.
views/{name}/
中创建页面级视图。Views层组合widgets、features、entities模块。

Step 6: Connect to App Router

步骤6:对接App Router

Wire views to Next.js routing.
page.tsx
imports from
@/views/{slice}
.
将views层与Next.js路由关联。
page.tsx
@/views/{slice}
导入组件。

Import Rules

导入规则

Allowed

允许的导入

  • Layer importing from layer below
  • Any layer importing from shared
  • Slice importing different slice in lower layer
  • 上层模块导入下层模块
  • 任意层导入shared层模块
  • 下层模块中的切片导入同层其他切片

Forbidden

禁止的导入

  • Layer importing from same or higher layer
  • Cross-slice imports within same layer
  • Shared importing from FSD layers
  • 模块导入同层或上层模块
  • 同层内跨切片导入
  • shared层导入任何FSD分层模块

Fixing Circular Dependencies

循环依赖修复方案

  1. Extract shared logic to lower layer (entities or shared)
  2. Create higher layer (widget) that imports both
  3. Review if slice should be split
  1. 将共享逻辑提取至更低层级(entities或shared层)
  2. 创建更高层级的模块(如widget)来导入存在循环依赖的模块
  3. 评估是否需要拆分现有切片

Public API Enforcement

公共API强制执行

Always use
index.ts
to control exports. Import from public API only:
typescript
// ✅ Correct
import { LoginForm } from '@/features/auth';

// ❌ Wrong (deep import)
import { LoginForm } from '@/features/auth/ui/LoginForm';
始终通过
index.ts
控制导出内容。仅从公共API导入:
typescript
// ✅ 正确写法
import { LoginForm } from '@/features/auth';

// ❌ 错误写法(深层导入)
import { LoginForm } from '@/features/auth/ui/LoginForm';

Migration Strategy (Bottom-up)

迁移策略(自底向上)

  1. Start with shared layer — extract UI, lib, API client
  2. Define entities — business domain objects
  3. Extract features — user interactions
  4. Build widgets — composite UI blocks
  5. Organize views — move page logic from page files
  6. Configure app layer — providers, styles
Migrate incrementally; run tests after each layer.
  1. 从shared层开始——提取UI组件、工具库、API客户端
  2. 定义entities层——业务领域对象
  3. 提取features层——用户交互模块
  4. 构建widgets层——复合UI块
  5. 组织views层——将页面逻辑从路由文件中迁移
  6. 配置app层——提供者、样式
采用增量迁移方式;完成每一层迁移后运行测试。

Best Practices

最佳实践

  • No cross-slice imports within same layer
  • Export through
    index.ts
    ; avoid
    export * 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-search
    not
    features/search-bar-component
  • Use TypeScript strict mode
  • 同层内禁止跨切片导入
  • 通过
    index.ts
    导出;避免
    export * from
    ;使用显式导出
  • shared/ui:为每个组件单独创建index文件以支持tree-shaking(详见public-api.md
  • 避免使用通用文件夹/文件命名:
    types.ts
    utils.ts
    components/
    ——使用基于领域的命名(详见code-smells.md
  • 测试文件与实现文件放在同一目录下
  • 保持切片聚焦;避免“上帝切片”
  • 按领域命名:
    features/product-search
    而非
    features/search-bar-component
  • 启用TypeScript严格模式

Troubleshooting

问题排查

Import path issues: Configure path aliases in
tsconfig.json
— see Configuration below.
Build errors: Clear
.next
, run
npm install
, restart dev server.
导入路径问题:在
tsconfig.json
中配置路径别名——详见下方配置部分。
构建错误:清理
.next
目录,运行
npm install
,重启开发服务器。

Configuration

配置说明

TypeScript Path Aliases

TypeScript 路径别名

json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/app/*": ["src/app/*"],
      "@/views/*": ["src/views/*"],
      "@/widgets/*": ["src/widgets/*"],
      "@/features/*": ["src/features/*"],
      "@/entities/*": ["src/entities/*"],
      "@/shared/*": ["src/shared/*"]
    }
  },
  "include": ["src"]
}
json
{
  "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)

ESLint(可选)

javascript
'no-restricted-imports': ['error', {
  patterns: [{
    group: ['@/views/*', '@/widgets/*'],
    message: 'Features cannot import from views or widgets',
  }],
}]
javascript
'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
开发过程中按需查阅以下资源:
核心FSD参考
  • layers-and-segments.md — 分层、切片(零耦合、切片组)、分段、@x跨模块引用、迁移指南(含v2.0→v2.1)
  • public-api.md — 公共API规则、@x跨模块导入、循环依赖、shared/ui tree-shaking、Steiger模式
  • code-smells.md — 反模式示例:分段缺失、通用文件夹/文件滥用
实现示例
  • examples.md — 完整示例:各分层结构、页面布局、鉴权、类型/DTO、API请求、领域化文件
可选内容
  • react-query.md — React Query + FSD:查询工厂、分页、QueryProvider配置
  • monorepo.md — Turborepo + FSD 结构方案
外部资源