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 andutils/
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
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/
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
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
- Use
- Atomic Design
- Works great inside
ui/
if you likeatoms/molecules
- Works great inside
- ESLint enforcement
- Use
eslint-plugin-boundaries
to auto-check layer rules
- Use
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)