Skills Plugins MCP Prompt Model 博客 我的中心
Development #react #image #design #api

feature-sliced-design

Official Feature-Sliced Design (FSD) v2.1 skill for applying the methodology to frontend projects. Use when the task involves organizing project structure with FSD layers, deciding where code belongs, placing static assets (images, icons, fonts, PDFs), grouping closely related slices, defining public APIs and import boundaries, resolving cross-imports or evaluating the @x pattern, deciding whether to create or remove an entity, evaluating whether the entities layer is needed at all, deciding where page layouts belong or whether to use the widgets layer (discouraged), deciding whether logic should remain local or be extracted, migrating from FSD v2.0 or a non-FSD codebase, integrating FSD with frameworks (Next.js App Router and Pages Router, Nuxt, Vite, Astro), or implementing common patterns such as authentication, API handling, Redux, and TanStack Query (React Query) within FSD.

DeepseekModel Curated skill Quality Excellent · 78 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=feature-sliced-skills-feature-sliced-design-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name feature-sliced-design description Official Feature-Sliced Design (FSD) v2.1 skill for applying the methodology to frontend projects. Use when the task involves organizing project structure with FSD layers, deciding where code belongs, placing static assets (images, icons, fonts, PDFs), grouping closely related slices, defining public APIs and import boundaries, resolving cross-imports or evaluating the @x pattern, deciding whether to create or remove an entity, evaluating whether the entities layer is needed at all, deciding where page layouts belong or whether to use the widgets layer (discouraged), deciding whether logic should remain local or be extracted, migrating from FSD v2.0 or a non-FSD codebase, integrating FSD with frameworks (Next.js App Router and Pages Router, Nuxt, Vite, Astro), or implementing common patterns such as authentication, API handling, Redux, and TanStack Query (React Query) within FSD. Feature-Sliced Design (FSD) v2.1 Source : fsd.how | Strictness can be adjusted based on project scale and team context. 1. Core Philosophy & Layer Overview FSD v2.1 core principle: "Start simple, extract when needed." Place code in pages/ first. Duplication across pages is acceptable and does not automatically require extraction to a lower layer. Extract only when the same code is currently being used in multiple places (not hypothetically), the usages do not always change together, and the boundary has a focused responsibility. Not all layers are required. Most projects can start with only shared/ , pages/ , and app/ . Add features/ and entities/ only when they provide clear value. Do not create empty layer folders "just in case." The widgets/ layer is discouraged (see the callout below). FSD uses 6 standardized layers, listed here from highest to lowest: app/ → App initialization, providers, routing pages/ → Route-level composition, owns its own logic widgets/ → Reusable UI blocks (discouraged, see the callout below) features/ → Reusable user interactions (only when used in 2+ places) entities/ → Reusable business domain models (only when used in 2+ places) shared/ → Infrastructure with no business logic (UI kit, utils, API client) This guide discourages using the Widgets layer. Widgets may seem useful for representing independent UI blocks. However, in real frontend code, UI blocks often include logic required for user flows, such as data fetching, state management, and event handling. In this case, the responsibilities of Features, which handle user flows, and Widgets, which handle UI blocks, can overlap, making the boundary between the two layers unclear. Not creating a widget does not mean simply moving that UI block to another layer. Compositions that are specific to a particular screen should stay in pages . When a user action is reused across multiple pages, both the action and the UI composition required to perform it should be extracted into features . Shared UI without business context should be separated into shared . UI such as app-wide layouts can be handled in app . This does not mean removing the widgets/ layer entirely. It means recommending against actively adopting it. Projects already using widgets can keep using them as before. See references/layer-structure.md for details and layout placement. Import rule : A module may only import from layers strictly below it. Cross-imports between slices on the same layer are forbidden. // ✅ Allowed import { Button } from "@/shared/ui/Button" ; // features → shared import { useUser } from "@/entities/user" ; // pages → entities // ❌ Violation import { loginUser } from "@/features/auth" ; // entities → features import { likePost } from "@/features/like-post" ; // features → features Note : The processes/ layer is deprecated in v2.1. For migration details, read references/migration-guide.md . 2. Decision Framework When writing new code, follow this tree: Step 1: Where is this code used? Used in only one page → keep it in that pages/ slice. Used in 2+ pages but duplication is manageable → keeping separate copies in each page is also valid. An entity or feature used in only one page → keep it in that page (Steiger: insignificant-slice ). Step 2: Is it reusable infrastructure with no business logic? UI components → shared/ui/ Utility functions → shared/lib/ API client, route constants → shared/api/ or shared/config/ Auth tokens, session management → shared/auth/ CRUD operations → shared/api/ Step 3: Is it a complete user action currently used in multiple places, with stable boundaries? Yes → features/ Uncertain, single use, or speculative reuse → keep in the page. Step 4: Is it a business domain model currently used in multiple places, with stable boundaries? Yes → entities/ Uncertain, single use, or speculative reuse → keep in the page. Step 5: Is it app-wide configuration? Global providers, router, theme → app/ Golden Rule: When in doubt, keep it in pages/ . Extract only when the same code is actively used in multiple places and the boundary is clear. 3. Quick Placement Table Scenario Single use Confirmed multi-use User profile form pages/profile/ui/ProfileForm.tsx features/profile-form/ Product card pages/products/ui/ProductCard.tsx entities/product/ui/ProductCard.tsx Product data fetching pages/product-detail/api/fetch-product.ts entities/product/api/ Auth token/session shared/auth/ (always) shared/auth/ (always) Auth login form pages/login/ui/LoginForm.tsx features/auth/ CRUD operations shared/api/ (always) shared/api/ (always) Generic Card layout shared/ui/Card/ Modal manager shared/ui/modal-manager/ Modal content pages/[page]/ui/SomeModal.tsx Date formatting util shared/lib/format-date.ts 4. Architectural Rules (MUST) These rules are the foundation of FSD. Violations weaken the architecture. If you must break a rule, ensure it is an intentional design decision and document the reason in code (a comment or ADR). 4-1. Import only from lower layers app → pages → widgets → features → entities → shared . Upward imports and cross-imports between slices on the same layer are forbidden. 4-2. Public API: every slice exports through index.ts External consumers may only import from a slice's index.ts . Direct imports of internal files are forbidden. // ✅ Correct import { LoginForm } from "@/features/auth" ; // ❌ Violation: bypasses public API import { LoginForm } from "@/features/auth/ui/LoginForm" ; Shared layer: Shared has no slices. Define a separate public API per segment ( shared/ui/index.ts , shared/api/index.ts , etc.) rather than one top-level shared/index.ts . This keeps imports from Shared organized by intent. Environment-specific public APIs A slice should normally expose its public API through a single index.ts . Ad-hoc customization is not recommended. If a single index.ts cannot preserve a runtime boundary, add an environment-specific entry point such as index.server.ts . See references/framework-integration.md . 4-3. No cross-imports between slices on the same layer If two slices on the same layer need to share logic, follow the resolution order in Section 7. Do not create direct imports. 4-4. Domain-based file naming (no desegmentation) Name files after the business domain they represent, not their technical role. Technical-role names like types.ts , utils.ts , helpers.ts mix unrelated domains in a single file and reduce cohesion. // ❌ Technical-role naming model/types.ts ← Which types? User? Order? Mixed? model/utils.ts // ✅ Domain-based naming model/user.ts ← User types + related logic model/order.ts ← Order types + related logic api/fetch-profile.ts ← Clear purpose 4-5. No business logic in shared/ Shared contains only infrastructure: UI kit, utilities, API client setup, route constants, assets. Business calculations, domain rules, and workflows belong in entities/ or higher layers. // ❌ Business logic in shared // shared/lib/userHelpers.ts export const calculateUserReputation = ( user ) => { ... }; // ✅ Move to the owning domain // entities/user/lib/reputation.ts export const calculateUserReputation = ( user ) => { ... }; 5. Recommendations (SHOULD) 5-1. Pages First: place code where it is used Place code in pages/ first. Extract to lower layers only when truly needed. Extraction is a design decision that affects the whole project, so the threshold should be high. What stays in pages: Large UI blocks used only in one page Page-specific forms, validation, data fetching, state management Page-specific business logic and API integrations Code that looks reusable but is simpler to keep local Evolution pattern: Start with everything in pages/profile/ . When the same user data is being consumed by another page (not hypothetically), extract the shared model to entities/user/ . Keep page-specific API calls and UI in the page. 5-2. Be conservative with entities The entities layer is highly accessible (almost every other layer can import from it), so changes propagate widely. Start without entities. shared/ + pages/ + app/ is valid FSD. Thin-client apps rarely need entities. Do not split slices prematurely. Keep code in pages. Extract to entities only when the same code is currently used by multiple consumers and the boundary is stable. Business logic does not automatically require an entity. Keeping types in shared/api and logic in the current slice's model/ segment may be sufficient. Place CRUD in shared/api/ . CRUD is infrastructure, not entities. Place auth data in shared/auth/ or shared/api/ . Tokens and login DTOs are auth-context-dependent and rarely reused outside authentication. For detailed guidance on keeping the entities layer clean (when to skip it entirely, how to isolate business contexts, why CRUD belongs in shared/api ), see references/excessive-entities.md . 5-3. Start with minimal layers // ✅ Valid minimal FSD project src/ app/ ← Providers, routing pages/ ← All page-level code shared/ ← UI kit, utils, API client // Add layers only when an actual use case requires them: // + features/ ← User interactions currently reused across multiple pages // + entities/ ← Domain models currently reused across pages or features // (widgets/ is discouraged; see Section 1 for where that code goes instead) 5-4. Validate with the Steiger linter Steiger is the official FSD linter. Key rules: insignificant-slice : Suggests merging an entity/feature into its page if only one page uses it. excessive-slicing : Suggests merging or grouping when a layer has too many slices. npm install -D @feature-sliced/steiger npx steiger src 6. Anti-patterns (AVOID) Do not adopt the widgets/ layer by default. UI blocks often include user-flow logic, making the boundary with Features unclear (see Section 1 for where widget-like code goes instead). Do not create entities prematurely. Data structures used in only one place belong in that place. Do not put CRUD in entities. Use shared/api/ . Consider entities only for complex transactional logic. Do not create a user entity just for auth data. Tokens and login DTOs belong in shared/auth/ or shared/api/ . Do not abuse @x . It is a necessary compromise, not a recommended pattern. The notation is for the entities layer only, and only when boundary merge is genuinely impossible. Features and widgets handle cross-imports through strategies A–D (see Section 7). Do not extract single-use code. A feature or entity used by only one page should stay in that page. Do not use technical-role file names. Use domain-based names (see Rule 4-4). Be cautious adding UI to entities. Entity UI tempts cross-imports from other entities. If you add UI segments to entities, only import them from higher layers (features, pages, app), never from other entities. Do not create god slices. Slices with excessively broad responsibilities should be split into focused slices (e.g., split user-management/ into auth/ , profile-edit/ , password-reset/ ). Do not create a top-level assets/ segment. Place static assets next to the code that uses them. See references/asset-handling.md . 7. Cross-Import Resolution Cross-imports are a code smell, not an absolute prohibition. The right strategy depends on the layer and the situation. Entities layer: prefer boundary merge, @x is last resort Cross-imports in entities are usually caused by splitting entities too granularly. Before reaching for @x , consider whether the boundaries should be merged. @x is a necessary compromise, not a recommended approach . Use it only when boundaries genuinely cannot be merged, and document why. Overuse locks entity boundaries together and increases refactoring cost. Features and widgets: four strategies (A, B, C, D) In features and widgets , choose based on context: Strategy A: Slice merge. Two slices always change together → merge. Strategy B: Push to entities. Shared domain logic → move to entities/ , keep UI in the feature. Strategy C: Compose from upper layer (IoC). The parent (pages or app) imports both slices and connects them via render props, slots, or DI. Strategy D: Public API access. When reuse is genuinely unavoidable, allow it only through the slice's index.ts . Never reach into model/ , store/ , or internal files. The @x notation is for the entities layer only. Features and widgets use strategies A–D above. Strictness depends on project context Cross-imports are dependencies that are generally best avoided, but sometimes used intentionally. Strictness varies by project context: Early-stage products with heavy experimentation: allowing some cross-imports may be a pragmatic speed trade-off. Long-lived or regulated systems (fintech, large-scale services): stricter boundaries pay off in maintainability and stability. If a cross-import is introduced, treat it as a deliberate choice and document the reasoning in code (a comment explaining why other strategies do not apply). For detailed code examples of each strategy, read references/cross-import-patterns.md . 8. Segments & Structure Rules Standard segments Segments group code within a slice by technical purpose: ui/ : UI components, styles, display-related code model/ : Data models, state stores, business logic, validation api/ : Backend integration, request functions, API-specific types lib/ : Internal utility functions for this slice config/ : Configuration, feature flags Layer structure rules App and Shared : No slices, organized directly by segments. Segments within these layers may import from each other. Pages, Widgets, Features, Entities : Slices first, then segments inside each slice. Slice groups (optional) : A group folder may contain related slices on the same layer for navigation purposes only. The group has no segments and no public API. See references/layer-structure.md for details. File naming within segments Always use domain-based names that describe what the code is about: model/user.ts ← User types + logic + store model/order.ts ← Order types + logic + store api/fetch-profile.ts ← Profile fetching api/update-settings.ts ← Settings update If a segment has only one domain concern, the filename may match the slice name (e.g., features/auth/model/auth.ts ). 9. Shared Layer Guide Shared contains infrastructure with no business logic . It is organized by segments only (no slices). Segments within shared may import from each other. Allowed in shared: ui/ : UI kit (Button, Input, Modal, Card) lib/ : Utilities (formatDate, debounce, classnames) api/ : API client, route constants, CRUD helpers, base types auth/ : Auth tokens, login utilities, session management config/ : Environment variables, app settings assets/ : Branding assets shared across the app (use sparingly; see references/asset-handling.md )
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。