[JB]
2026.03.28기술

Next.js 앱에 FSD 적용하기

App Router의 page 개념을 유지하면서 widgets / features / entities로 코드를 분리한 사례를 정리한다.

Layer 매핑

  • Appapps/notepad/app/ (Next App Router, page만)
  • Widgets — 페이지 섹션 조립
  • Features — 사용자 액션 (command hook)
  • Entities — 도메인 모델 + read
  • Sharedlib/, packages/

의존성 방향

app → widgets → features → entities → shared

상위에서 하위로만. 같은 layer 슬라이스 간 import도 금지.

CQRS-strict 변형

정통 FSD는 entities/features에 ui를 둘 수 있지만, 우리는 read/write 책임을 명확히 분리하기 위해 ui를 widgets 한 곳에만 둔다.

// entities/post/api/queries.ts — read만
export const postListQueryOptions = () =>
  queryOptions({ queryKey: postKeys.list.queryKey, queryFn: postKeys.list.queryFn });

Trade-off

  • ✅ 도메인-UI 결합 약함, 재사용성↑
  • ✅ entity는 비-UI라 unit test 쉬움
  • ⚠️ 같은 도메인의 UI가 흩어지는 느낌이 들 수 있음 → widget 슬라이스 그룹핑으로 보완

결론

가벼운 학습 프로젝트에선 정통 FSD가 과해 보일 수 있지만, 한번 자리잡으면 새 페이지/기능 추가가 일정한 패턴을 따른다.