Feature-Sliced Design - 프론트엔드 아키텍처의 또 다른 선택지
프론트엔드 프로젝트가 점점 커지면서 가장 먼저 고민하게 되는 게 폴더 구조다. 처음엔 components, pages, utils 정도로 시작했다가, 어느 순간 components 폴더 안에 수십 개의 파일이 쌓이면서 "이거 어디에 둬야 하지?"라는 고민이 반복된다.
플로우웍스 프론트엔드를 개선하면서 나도 이런 고민을 했다. UI 컴포넌트 중심으로 구조화하는 Atomic Design을 알아보던 중, 조금 다른 접근법을 발견했다. 바로 Feature-Sliced Design(FSD) 이다.
Feature-Sliced Design이란?
Feature-Sliced Design은 프론트엔드 애플리케이션을 구조화하는 아키텍처 방법론이다. Atomic Design이 UI 컴포넌트의 크기와 복잡도를 기준으로 나눈다면, FSD는 비즈니스 도메인과 영향 범위 를 기준으로 코드를 나눈다.
핵심 목표는 명확하다. 비즈니스 요구사항이 계속 변해도 프로젝트를 이해하기 쉽고 안정적으로 유지하는 것. 새로운 기능을 추가하거나 기존 기능을 수정할 때, 어디에 코드를 둬야 할지 명확하고, 다른 부분에 미치는 영향을 최소화하는 구조를 만드는 게 목표다.
3가지 핵심 개념
FSD는 세 가지 개념으로 프로젝트를 구조화한다.
1. Layers (레이어)
코드를 영향 범위 에 따라 7개 레이어로 분리한다. 위에서 아래로 갈수록 더 범용적이고 재사용 가능한 코드가 위치한다.
- app: 애플리케이션 진입점, 전역 설정 (라우터, 스토어, 전역 스타일)
- pages: 라우트별 페이지 (URL과 1:1 매칭)
- widgets: 독립적인 UI 블록 (헤더, 사이드바 같은 큰 단위)
- features: 사용자 시나리오 (로그인, 장바구니 추가, 좋아요 같은 기능)
- entities: 비즈니스 엔티티 (User, Product, Order 같은 도메인 모델)
- shared: 재사용 가능한 유틸리티 (UI 킷, API 클라이언트, 헬퍼 함수)
2. Slices (슬라이스)
각 레이어 안에서 도메인별로 코드를 분리한다. 예를 들어 features 레이어 안에 auth, cart, wishlist 같은 슬라이스가 존재한다.
3. Segments (세그먼트)
슬라이스 안에서 기술적 목적 에 따라 분리한다.
- ui: React 컴포넌트
- model: 상태 관리 (store, hooks)
- api: API 호출 함수
- lib: 해당 슬라이스 전용 유틸리티
폴더 구조 예시
실제 프로젝트에서는 이런 식으로 구성된다.
src/
├── app/ # 앱 진입점
│ ├── providers/ # 전역 Provider (Redux, Router)
│ ├── styles/ # 전역 스타일
│ └── index.tsx
├── pages/ # 페이지 레이어
│ ├── home/
│ ├── product-detail/
│ └── checkout/
├── widgets/ # 위젯 레이어
│ ├── header/
│ └── footer/
├── features/ # 기능 레이어
│ ├── auth/ # 인증 기능
│ │ ├── ui/ # 로그인 폼 컴포넌트
│ │ ├── model/ # 인증 상태 관리
│ │ └── api/ # 로그인 API
│ ├── add-to-cart/ # 장바구니 추가 기능
│ │ ├── ui/
│ │ └── model/
│ └── wishlist/
├── entities/ # 엔티티 레이어
│ ├── user/ # User 도메인
│ │ ├── ui/ # UserCard 같은 UI
│ │ ├── model/ # User 타입 정의
│ │ └── api/ # User API
│ └── product/
└── shared/ # 공유 레이어
├── ui/ # Button, Input 같은 공통 컴포넌트
├── api/ # axios 인스턴스
└── lib/ # 유틸리티 함수
핵심 규칙: 단방향 의존성
FSD의 가장 중요한 규칙은 의존성의 방향 이다.
-
상위 레이어는 하위 레이어만 참조할 수 있다
pages→features,entities,shared참조 가능features→entities,shared참조 가능entities→shared만 참조 가능- 역방향은 불가능
-
같은 레이어의 슬라이스끼리는 참조할 수 없다
features/auth→features/cart참조 불가- 각 슬라이스는 독립적이어야 함
이 규칙을 지키면 높은 응집도, 낮은 결합도 를 자연스럽게 달성할 수 있다. 한 기능을 수정할 때 다른 기능에 영향을 주지 않는 구조가 만들어진다.
Atomic Design과 뭐가 다른가?
Atomic Design을 알아보다가 FSD를 발견했는데, 두 방법론은 접근 방식이 꽤 다르다.
Atomic Design 은 UI 컴포넌트를 크기와 복잡도 기준으로 나눈다. Atoms(버튼, 인풋) → Molecules(검색바) → Organisms(헤더) → Templates → Pages 순으로 조합해 나간다. UI 중심 프로젝트나 디자인 시스템을 만들 때 직관적이고, 컴포넌트 재사용에 초점을 맞춘다.
FSD 는 비즈니스 도메인과 영향 범위를 기준으로 나눈다. "이 코드가 어디까지 영향을 미치는가"와 "어떤 비즈니스 기능인가"가 기준이다. 비즈니스 로직이 복잡한 애플리케이션에서 모듈 간 의존성을 관리하는 데 강점이 있다.
둘 중 뭐가 더 나은 게 아니라, 프로젝트 성격에 따라 선택하면 된다. UI 컴포넌트 재사용이 중요한 프로젝트라면 Atomic Design, 복잡한 비즈니스 로직과 기능들을 관리해야 한다면 FSD가 더 적합할 수 있다.
언제 사용하면 좋을까?
FSD는 모든 프로젝트에 맞는 건 아니다.
적합한 경우:
- 복잡하거나 장기적으로 유지보수할 프로젝트
- 팀 규모가 크고 여러 사람이 동시에 개발하는 경우
- 비즈니스 로직이 자주 변경되는 프로덕트
부적합한 경우:
- 빠르게 만들어야 하는 프로토타입
- 소규모 프로젝트나 간단한 랜딩 페이지
- 팀원들이 FSD 개념에 익숙하지 않고 학습 비용이 부담스러운 경우
현재 은행, 핀테크, B2B SaaS, 이커머스처럼 복잡한 비즈니스 로직을 다루는 프로젝트들에서 FSD를 사용하고 있다고 한다.
실제로 누가 쓸까?
FSD를 직접 언급하진 않지만, 비슷한 원칙으로 프로젝트를 구조화하는 회사들이 있다.
- Shopify - Polaris 디자인 시스템에서 도메인별 레이어 분리
- Atlassian - Jira, Confluence, Trello 등에서 feature 기반 구조 사용
- IBM - Carbon Design System에서 비즈니스 도메인 중심 구조
마치며
프론트엔드 아키텍처에는 정답이 없다. Atomic Design, FSD, 아니면 그냥 components와 pages로만 나누는 것도 프로젝트에 맞다면 괜찮다.
다만 프로젝트가 점점 복잡해지고, "이거 어디에 둬야 하지?"라는 고민이 반복된다면, FSD 같은 방법론을 한번 살펴보는 것도 좋다. 당장 도입하지 않더라도, 이런 구조화 방식이 있다는 걸 알아두면 나중에 도움이 될 수 있다.
플로우웍스에 FSD를 바로 적용할지는 아직 모르겠지만, 적어도 "프론트엔드를 어떻게 구조화할 것인가"에 대한 하나의 좋은 레퍼런스를 얻은 것 같다.