Recipes
Build real features, step by step
Each recipe starts from a generated project and uses only released CLI commands. Generated files are scaffolding: the comments marked // your code show where your product logic goes. Examples use React + Vite; the commands are the same for every framework.
1. A product catalog
Goal: list products, open one, and add it to a cart, with each concept in its own slice.
npx create-fsd-architecture@latest shop --framework react-vite --yes
cd shop
npx create-fsd-architecture@latest -g entity product --dry-run
npx create-fsd-architecture@latest -g entity product
npx create-fsd-architecture@latest -g feature add-to-cart
npx create-fsd-architecture@latest -g widget product-list
npx create-fsd-architecture@latest -g page catalogThe entity owns the Product type and ProductCard. The feature owns the user action. The widget composes both, and the page places the widget on a route that the CLI registers for you.
// widgets/product-list/ui/product-list.tsx (your code)
import { ProductCard, type Product } from "@/entities/product";
import { AddToCart } from "@/features/add-to-cart";
export function ProductList({ products }: { products: Product[] }) {
return (
<ul>
{products.map((product) => (
<li key={product.id}>
<ProductCard product={product} />
<AddToCart productId={product.id} />
</li>
))}
</ul>
);
}The AddToCart and ProductList components are yours to write inside the generated slices. Export them from each slice's index.ts so other layers import only the public API. Need several entities at once? Batch them: -g entity product category review.
2. A site shell with layout presets
Goal: ship accessible navigation, footer, and content pages in minutes.
npx create-fsd-architecture@latest -g widget navbar sidebar footer bottom-bar
npx create-fsd-architecture@latest -g page home about consultThese names are presets: the widgets render labelled landmarks such as <nav aria-label>, and the pages come with content sections and, for consult, a contact form with required fields. Any other name produces an empty slice instead. Edit the generated copy, then wire the widgets into your app layout.
3. Sign in with Supabase
Goal: replace the example auth requests with real Supabase calls.
npx create-fsd-architecture@latest -g feature auth --auth-provider supabase --dry-run
npx create-fsd-architecture@latest -g feature auth --auth-provider supabase
npm install @supabase/supabase-js// app/providers/supabase.ts (your code)
import { createClient } from "@supabase/supabase-js";
import { configureSupabaseAuth } from "@/features/auth";
const client = createClient(publicUrl, publishableKey);
configureSupabaseAuth(client);Use only the public publishable or anon key in the browser. The adapter is in preview: test sign-up, password recovery, and RLS in a staging project before production. Details are on Feature status.
4. Add FSD structure to an existing app
Goal: introduce layers and segments without touching existing files.
npx create-fsd-architecture@latest -g shared --segments ui,lib,api --root src --dry-run
npx create-fsd-architecture@latest -g shared --segments ui,lib,api --root src
npx create-fsd-architecture@latest -g feature checkout --segments ui,model,api --root srcStructure-only mode creates missing folders and empty public APIs and never overwrites a file. Move code into the new slices one at a time, and keep the app building after each move. For a guided migration, use the AI Agent Skill.
5. Guard the architecture in CI
Goal: fail a pull request that breaks layer or public-API rules.
npm install -D steiger @feature-sliced/steiger-plugin# .github/workflows/architecture.yml
name: Architecture
on: [pull_request]
jobs:
fsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx create-fsd-architecture@latest check --architecture
- run: npx create-fsd-architecture@latest upgrade --checkcheck --architecture exits non-zero on violations. upgrade --check exits 2 when a CLI upgrade is available, so drop that step or allow exit code 2 if you only want a warning.