$npx -y skills add ccheney/robust-skills --skill feature-slicingProactively apply when creating new features/components/pages or setting up frontend project structure. Triggers on FSD, feature slicing, Feature-Sliced Design, frontend architecture, layer structure, module boundaries, scalable frontend, slice organization, public API, barrel ex
| 1 | # Feature-Sliced Design Architecture |
| 2 | |
| 3 | Frontend architecture methodology (spec v2.1) with a strict layer hierarchy and one import rule. FSD organizes code by **business domain** rather than technical role. |
| 4 | |
| 5 | > **Official Docs:** [feature-sliced.design](https://feature-sliced.design) | **GitHub:** [feature-sliced](https://github.com/feature-sliced) |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## THE IMPORT RULE (Critical) |
| 10 | |
| 11 | **A module in a slice may only import slices from layers strictly below. Never sideways or upward.** This is what keeps slices replaceable and dependencies traceable — every violation you allow becomes an invisible coupling someone else trips over. |
| 12 | |
| 13 | ``` |
| 14 | app → pages → widgets → features → entities → shared |
| 15 | ↓ ↓ ↓ ↓ ↓ ✓ |
| 16 | ✓ ✓ ✓ ✓ ✓ (external only) |
| 17 | ``` |
| 18 | |
| 19 | | Violation | Example | Fix | |
| 20 | |-----------|---------|-----| |
| 21 | | Cross-slice (same layer) | `features/auth` → `features/user-profile` | Move shared code to a lower layer, or compose both in the page/widget above | |
| 22 | | Upward import | `entities/user` → `features/auth` | Move the needed code down | |
| 23 | | Shared importing up | `shared/` → `entities/` | Shared depends only on external packages | |
| 24 | | Cross-entity | `entities/order` → `entities/product` internals | Use `@x` notation (entities layer only) | |
| 25 | |
| 26 | **Exception:** `app/` and `shared/` are each "a layer and a slice at the same time" — they divide directly into segments, and their segments may freely import each other. |
| 27 | |
| 28 | --- |
| 29 | |
| 30 | ## Layer Hierarchy |
| 31 | |
| 32 | | Layer | Purpose | Has Slices | Required | |
| 33 | |-------|---------|------------|----------| |
| 34 | | `app/` | Initialization, routing, providers, global styles | No (segments only) | Yes | |
| 35 | | `pages/` | Route-based screens — **the default home for most code** | Yes | Yes | |
| 36 | | `widgets/` | Large self-sufficient UI blocks reused across pages; may own their data fetching and logic | Yes | No | |
| 37 | | `features/` | User interactions reused across pages (login, add-to-cart) | Yes | No | |
| 38 | | `entities/` | Business domain models reused across pages (user, product) | Yes | No | |
| 39 | | `shared/` | Reused infrastructure: UI kit, API client, route constants, utilities. No knowledge of domain slices — but it may be app-aware (your backend's client, your route paths) | No (segments only) | Yes | |
| 40 | |
| 41 | The `processes/` layer is **deprecated** — move its contents to `features/` and `app/`. |
| 42 | |
| 43 | **Minimal setup:** `app/`, `pages/`, `shared/`. A small app with 5 routes does not need entities, features, or widgets — adding them "for completeness" spreads single-use code across the tree and negates FSD's cohesion benefit. Add a layer only when something is genuinely reused by 2+ pages. |
| 44 | |
| 45 | --- |
| 46 | |
| 47 | ## Pages First (v2.1 default) |
| 48 | |
| 49 | When unsure where code goes, **put it in the page slice that uses it** — including forms, data logic, and large UI blocks. Extract downward only when a second page needs it. Why: page-local code is found instantly by newcomers; premature entities/features force jumping through several folders to change one user flow. |
| 50 | |
| 51 | ``` |
| 52 | Where does this code go? |
| 53 | ├─ Used by exactly ONE page → that page's slice (even logic/forms) |
| 54 | ├─ App-wide config, providers, routing → app/ |
| 55 | ├─ Domain-agnostic or infra code → shared/ |
| 56 | ├─ Reused across pages: |
| 57 | │ ├─ Large UI block with own logic → widgets/ |
| 58 | │ ├─ User action (verb) → features/ |
| 59 | │ └─ Domain model/data (noun) → entities/ |
| 60 | ``` |
| 61 | |
| 62 | ### "Feature or Entity?" |
| 63 | |
| 64 | | Entity (noun) | Feature (verb) | |
| 65 | |---------------|----------------| |
| 66 | | `user` — user data model | `auth` — login/logout actions | |
| 67 | | `product` — product info | `add-to-cart` — adding to cart | |
| 68 | | `comment` — comment data | `write-comment` — creating comments | |
| 69 | |
| 70 | Entities represent THINGS with identity. Features represent ACTIONS with side effects. Not everything is a feature — an interaction used on one page stays in that page. |
| 71 | |
| 72 | ### "Which segment?" |
| 73 | |
| 74 | Segments divide a slice by technical purpose: |
| 75 | |
| 76 | ``` |
| 77 | ├─ ui/ → components, styles, formatters |
| 78 | ├─ api/ → backend calls, DTOs, mappers |
| 79 | ├─ model/ → types, schemas, stores, business logic |
| 80 | ├─ lib/ → slice-internal utilities |
| 81 | └─ config/ → feature flags, constants |
| 82 | ``` |
| 83 | |
| 84 | Name segments by **purpose**, not essence: `api/`, `model/`, `lib/` — never `hooks/`, `components/`, `types/`, `utils/`. Purpose names tell a reader what the code is *for*; essence names just restate the file ext |