DEV Community

nyaomaru
nyaomaru

Posted on

Let’s Learn Feature-Sliced Design (FSD)

Hi everyone, I’m @nyaomaru, a frontend engineer! 👋

In the age of AI coding, the most valuable thing humans bring to the table is design.

But… have you ever faced the chaos of “where the heck should I put this file?” because every team had its own folder rules? 😅

That’s where Feature-Sliced Design (FSD) comes in.

Implementing Clean Architecture in frontend projects has always been tricky. Along the way we’ve seen approaches like feature-based folders, Atomic Design, and more.
Next.js recently pushed the App Router as a new baseline too.

But as AI joins us in large-scale projects, having a flexible yet robust architecture is becoming critical because AI-generated code often varies in granularity.

By defining clear “shelves” with FSD, AI and humans stop stepping on each other’s toes.

That’s why we should learn FSD together!
This post is aimed at people who’ve never touched it before.
The goal is to get a feel for the concept, not a deep dive.

👉 Official docs: https://feature-sliced.github.io/documentation/

 

What is FSD?

Feature-Sliced Design (FSD) is a frontend-first architecture that
“cuts your app by feature, fixes dependency direction (top → down only), and prevents spaghetti.”

Why bother?

  • Escape from components/ hell and utils/ chaos: group by feature
  • Enforce top → down only dependencies: no more circular imports
  • Strong for large-scale frontend projects (but a bit too much for small libs)

3 Core Concepts

Term One-liner description
Layer The “shelf” that sets dependency direction
Slice The “drawer” for each domain
Segment The “divider” inside a drawer

FSD vs App Router?

Viewpoint FSD App Router
Split axis Features + responsibilities URL hierarchy
Dependency Layer rules URL hierarchy only
Example features/user-profile app/(user)/profile/page.tsx

👉 In short: App Router is page-first, FSD is feature-first. Similar vibe, different purpose.

 

Layers

FSD splits your app into 6 responsibility-based layers 👇
(processes/ was deprecated, so not included here)

app/      # entrypoint: routing, theme, i18n, framework-level setup
pages/    # page-level UI, switched by URL
widgets/  # UI composites for use-cases (Card+Table+Form)
features/ # functional behavior: auth, search query builder, etc.
entities/ # domain models: User, Product, Order
shared/   # cross-cutting stuff: UI, hooks, libs, types
Enter fullscreen mode Exit fullscreen mode

Example with Button:

  • shared/ui/Button.tsx → generic button usable anywhere
  • features/auth/ui/LoginButton.tsx → login-specific button with behavior

👉 This makes responsibilities explicit and keeps your top-level folders unified.

Dependency Rule

Only higher layers can call lower ones:

From Allowed to use…
app/ everything
pages/ widgets and below
widgets/ features, entities, shared
features/ entities, shared
entities/ shared only
shared/ no upward calls (shared-only)

Think of it like a company:
the CEO can direct employees, but employees can’t boss around the CEO.
That’s how we avoid spaghetti. 🍝

Slices

Within each layer, code is split by business domain:

pages/
  user-profile/
  search-transaction/
  order-history/

features/
  user-login/
  user-update-password/
  search-query/
  search-suggest/

entities/
  user/
  product/
  order/
Enter fullscreen mode Exit fullscreen mode

Slices are independent — you generally can’t reach into another slice’s internals.
But you can expose a public API via @x for controlled cross-slice access.

Segments

Inside a slice, further organize by purpose:

ui/     # components, styles, presentation
api/    # API calls, types, response mappers
model/  # store, schemas, types, business logic
lib/    # helpers, date utils, etc.
config/ # constants, flags
Enter fullscreen mode Exit fullscreen mode

This keeps display logic and business logic separate.
For app/ and shared/, custom segments are allowed since projects differ.

 

Why adopt FSD?

  • 🧱 Consistency
    • Same folder structure everywhere
    • New devs instantly know “where things live”
  • 🔒 Stability
    • Slices isolate features → fewer unintended side effects
    • No more “scary code nobody wants to touch”
  • 🔁 Reusability
    • shared/, entities/, features/ hold reusable pieces
    • Easier to find & reuse across the app (and by AI!)
  • 🧠 Flexibility
    • Clear “place to put new stuff” when requirements expand
  • 🤖 AI-Friendly
    • AI can respect the structure if you feed it rules (Cursor, Claude, Codex and so on)
    • Less friction in human–AI collaboration

 

Tips & Gotchas

  • Entities vs Features
    • entities/ = nouns → User, Product, Cart
    • features/ = verbs → login, addToCart, searchForm
  • Cross-imports with @x
    • Use @x as the “public API window” to safely reuse across slices
  • Atomic Design
    • Works great inside ui/ if you like atoms/molecules
  • ESLint enforcement
    • Use eslint-plugin-boundaries to auto-check layer rules

 

Wrap-up: Design is the Key Skill in the AI Era

FSD boils down to 3 pieces:

Piece Role In one phrase
Layer Dependency shelf “no directionless imports”
Slice Business drawer “this feature lives here”
Segment Internal partition “UI / API / model split”

Why it matters with AI

  • AI-written code has a clear “home” → review cost drops
  • ESLint enforces rules → fewer human mistakes
  • Features are isolated → you can literally tell GPT “modify this slice”

👉 Try applying it to just one screen or feature.
30 minutes of structuring can feel like cutting a path through a messy forest.

 

What’s Next

In the next post, we’ll look at FSD in practice: actually building something with it. Stay tuned! 🚀

 

✂️ That’s the gist!

I’m curious: Have you tried FSD in your projects?
Did it help, or did you hit any challenges?

Drop your thoughts in the comments!
I’d love to hear how others are approaching frontend architecture! ✨

Top comments (0)