Methodology
FSD concepts in five minutes
Feature-Sliced Design organizes frontend code by what it does for the product, not by file type. Three ideas carry the whole method: layers, slices, and segments. This page explains them and shows where the CLI puts each one. The official FSD documentation remains the reference for the methodology itself.
Layers
Layers are the top-level folders under your source root. They are ordered from the most specific (app) to the most generic (shared). Every generated project has all six.
| Layer | What belongs here | Example |
|---|---|---|
| app | Entry point, providers, routing, global styles. | app/providers |
| pages | Full routed screens composed from lower layers. | pages/checkout |
| widgets | Large self-contained UI blocks reused across pages. | widgets/navbar |
| features | User interactions that bring business value. | features/add-to-cart |
| entities | Business entities the product works with. | entities/product |
| shared | Reusable code with no business meaning. | shared/ui/button |
The import rule
A module may import only from layers below its own. A page can use widgets, features, entities, and shared code; an entity can use only shared code. Slices on the same layer do not import each other, so features/cart never imports features/auth. When two features need to cooperate, compose them one layer up, in a widget or page.
// pages/checkout/ui/checkout-page.tsx
import { CartSummary } from "@/widgets/cart-summary"; // ✓ lower layer
import { ProductCard } from "@/entities/product"; // ✓ lower layer
// features/cart/model/cart.ts
import { useSession } from "@/features/auth"; // ✗ same layer
import { CheckoutPage } from "@/pages/checkout"; // ✗ higher layerapp and shared have no slices, so their segments may import each other freely within the layer.
Slices
Inside pages, widgets, features, and entities, code is split into slices named after a business concept: product, cart, checkout. A slice groups everything that changes together, so deleting a slice removes the concept cleanly.
Segments
Inside a slice, segments group code by technical purpose. Use only the segments a slice needs.
| Segment | Contents |
|---|---|
| ui | Components, styles, and view-only formatting. |
| model | Types, schemas, stores, and business logic. |
| api | Requests and data mapping for this slice. |
| lib | Helpers used inside the slice. |
| config | Constants and feature flags. |
Public API
Each slice exposes an index.ts. Other layers import only from that file, never from a path inside the slice. This keeps internals free to change and makes the slice boundary explicit.
// ✓ through the public API
import { ProductCard } from "@/entities/product";
// ✗ reaching into the slice
import { ProductCard } from "@/entities/product/ui/product-card";What the CLI generates
Generators create a slice with its segments and public API, then wire routes or stores when the layer needs it. For example:
npx create-fsd-architecture@latest -g entity productsrc/entities/product/
├── index.ts # public API
├── model/product.types.ts # Product type
└── ui/product-card.tsx # ProductCard componentExact file names follow each framework's conventions (Vue and Svelte components, Next.js and Nuxt routes). Preview any command with --dry-run, and see the slice generator for every layer.
Checking the rules
The CLI creates the structure; it does not police imports by itself. Install Steiger and run npx create-fsd-architecture@latest check --architecture to lint layer and public-API violations in CI.