Atomic Design 적용 경험을 바탕으로 한 FSD 도입과 경계 조정
2026.10.04 · 6분
개요
Atomic Design을 써 본 경험에서 FSD를 고른 이유와, 적용하면서 바꾼 분류 기준을 적은 기록입니다.
| 항목 | 내용 |
|---|---|
| 유형 | 구조 선택·개발 규칙 조정 |
| 기록 범위 | FSD 선택 근거, 레이어별 책임, widgets 분류 조정, features 구조 개선안 |
| 관련 영역 | 도메인·공통 영역 구분, UI·비즈니스 로직 배치, 컴포넌트 조합 |
1. 상황과 제약
예전에 Atomic Design을 적용할 때 컴포넌트 크기나 조합 정도만으로는 분류가 안 되는 경우가 있었습니다. 같은 UI를 molecules, organisms, templates 중 어디에 둘지 판단할 기준이 분명하지 않았습니다.
프로젝트가 커지자 organisms에 도메인이 들어간 컴포넌트와 일반 UI가 섞여 쌓였습니다. 페이지 전용 컴포넌트를 pages/{도메인}/components에 두기도 했지만, 다른 페이지에서 다시 쓰게 되면 공통 영역으로 옮길지 또 판단해야 했습니다.
UI 기준으로 나누다 보니 비즈니스 로직을 컴포넌트 안에서 처리할지, 페이지에서 처리해 넘길지도 애매했습니다. 페이지 하나가 로직을 너무 많이 떠안거나, 관련 로직이 여기저기 흩어지기도 했습니다.
그래서 컴포넌트를 나누는 기준에 요구사항과 연결된 도메인·행위를 넣어 보려고 FSD를 택했습니다.
2. 검토와 판단
레이어에는 큰 책임을, 슬라이스에는 도메인이나 사용자 행위를, 세그먼트에는 API·타입·로직·UI 같은 역할을 담기로 했습니다.
아래는 적용 경험과 참고 자료를 바탕으로 정리한 컨벤션입니다. entities는 명사·Read 중심, features는 동사·CUD 중심으로 나누는 것이 이 프로젝트에서 정한 분류 기준입니다.
| 영역 | 역할별 책임 |
|---|---|
app | 전역 스타일, Provider, 라우팅 등 프로젝트 실행 설정 |
pages | 라우트에 연결되는 페이지와 화면 조합 |
widgets | 여러 도메인 또는 entity·feature를 조합한 의미 있는 UI 단위 |
features | 생성·수정·삭제 등 사용자 행위와 관련된 로직·UI |
entities | 도메인의 조회, 타입, 표현과 도메인 전용 UI |
shared | 특정 도메인에 종속되지 않는 공용 함수·타입·UI |
레이어는 app → pages → widgets → features → entities → shared 방향으로, 자기보다 아래 레이어만 참조하도록 했습니다. processes는 쓰지 않았습니다.
슬라이스 안은 필요에 따라 , , , , , 로 나눴습니다. 각각 API 요청, 비즈니스 로직, 공통 함수, 타입·스키마, 상태, UI를 두는 곳입니다.
3. 적용 과정과 기준 조정
명명 규칙과 외부 공개 기준 정리
레이어별 역할과 함께 명명 규칙도 정했습니다. 폴더는 kebab-case, 컴포넌트 파일은 PascalCase, 훅은 use 접두사를 쓰고, 외부에 공개할 항목은 index.ts에서 내보냅니다.
테이블 구성 요소의 역할을 나눔
테이블과 행의 수정·삭제 기능을 조합하는 경우를 예로 들면 레이어별 역할은 다음과 같습니다.
| 구성 요소 | 배치 기준 |
|---|---|
| 도메인 정보가 없는 공용 테이블 UI | shared |
| 도메인 컬럼과 조회 내용을 가진 테이블 | entities |
| 행에서 실행하는 수정·삭제 기능 | features |
| 테이블과 행의 기능을 함께 조합한 UI | widgets |
단순 컨테이너가 widgets에 모이는 문제를 조정
처음에는 도메인이 들어간 재사용 컴포넌트를 widgets로 분류했습니다. 그러자 Dialog·Sheet·Card 등을 감싸기만 하는 컴포넌트까지 widgets에 몰렸습니다.
그래서 컨테이너로 감싸기만 하는 컴포넌트는 해당 슬라이스의 ui에 두도록 기준을 바꿨습니다. 에는 도메인이나 사용자 행위를 조합하는 컴포넌트를 둡니다.
4. 정리와 남은 개선 방향
Atomic Design을 쓸 때는 컴포넌트가 버튼처럼 작은 단위인지, 여러 개를 합친 큰 단위인지만 보고 위치를 정했습니다. 이번에는 크기에 더해 어느 도메인에 속하는지, 어떤 행위를 하는지, 어떤 역할을 맡는지도 함께 따졌습니다.
features 바로 아래에 기능별 폴더를 둔 구성
features 폴더에는 처음에 기능별 슬라이스를 바로 아래에 두고 create-admin, update-user처럼 「행위-대상」 순서로 이름을 붙였습니다. 슬라이스 안에는 그 기능의 API 요청, 로직, 타입, UI를 같이 넣었습니다.
폴더로 보면 이런 모양입니다.
features/
├── create-admin/
├── create-user/
├── duplicated-user/
├── update-admin/
└── update-user/폴더 이름만 봐도 무슨 기능인지는 알 수 있습니다. 대신 관리자와 사용자처럼 도메인이 다른 기능이 모두 같은 깊이에 늘어서 있습니다.
같은 도메인의 기능이 흩어지고 CUD로 설명하기 어려운 기능이 생긴 문제
이름순으로 정렬하면 create-admin과 create-user처럼 행위가 같은 폴더끼리 붙습니다. 그래서 사용자 도메인에 어떤 기능이 있는지 보려면 create-user, duplicated-user, update-user를 하나씩 찾아야 했습니다. 도메인 단위로 코드를 모으려고 FSD를 택했는데, 정작 features 안에서는 도메인을 다시 눈으로 골라내야 했습니다.
기능을 생성·수정·삭제(CUD) 중심으로 정의한 것도 걸렸습니다. 중복 확인(duplicated-user)처럼 셋 중 어디에도 딱 맞지 않는 행위가 있었고, 이런 기능도 로직과 UI를 한곳에 묶어야 했습니다. CUD만으로는 features에 무엇이 들어가는지 설명하기 어려웠습니다.
도메인으로 먼저 묶고 그 아래에 기능을 두는 개선안
앞으로는 features 아래에 admin, user 같은 도메인 폴더를 먼저 두고, 그 안에 기능별 슬라이스를 넣는 방식을 생각하고 있습니다.