Ch13. 레퍼런스와 아키텍처 결정 기록
ADR 템플릿, 기술 선택 근거, 전체 참고 문헌
ADR(Architecture Decision Record) 작성법
엔터프라이즈 프로젝트에서는 "왜 이 기술을 선택했는가"를 기록하지 않으면, 6개월 후 아무도 그 이유를 설명하지 못합니다. ADR은 이를 해결합니다.
# ADR-001: 모노레포 도구로 Turborepo 선택
## 상태
승인됨 (2026-01-15)
## 맥락
- 4개 Next.js 앱 + 6개 공유 패키지로 구성된 프로젝트
- CI 빌드 시간이 15분을 초과하기 시작
- 팀원 8명이 동시에 다른 앱을 작업
## 결정
Turborepo를 빌드 오케스트레이션 도구로 선택한다.
## 대안
- **Nx**: 플러그인 생태계가 풍부하나, 학습 곡선이 높고 설정이 복잡
- **Bazel**: 대규모에 적합하나, JS/TS 생태계 지원이 제한적
- **Lerna**: 유지보수 모드, 캐싱 없음
## 근거
- Vercel 생태계와 네이티브 통합 (Remote Cache, turbo-ignore)
- 제로 설정에 가까운 초기 도입 비용
- content-aware hashing으로 CI 시간 80% 단축 기대
## 결과
- turbo.json에 파이프라인 정의
- Vercel Remote Cache 활성화
- CI 빌드 시간 15분 → 3분으로 단축docs/adr/
├── ADR-001-turborepo.md
├── ADR-002-app-router.md
├── ADR-003-yarn-4.md
├── ADR-004-vitest.md
└── template.md이 핸드북의 기술 선택 근거
| 기술 | 선택 이유 | 대안 | 대안을 배제한 이유 |
|---|---|---|---|
| Turborepo 2.9+ | Vercel 네이티브, --affected, worktree cache sharing, structured logs | Nx, Bazel | Nx는 과도한 설정, Bazel은 JS 지원 미흡 |
| Yarn 4 | PnP 지원, workspace 프로토콜, 속도 | pnpm, npm | pnpm도 좋은 선택이나 Vercel 공식 예제가 Yarn 기반 |
| Next.js 16.2+ App Router | RSC, Cache Components, Turbopack 기본, proxy.ts | Pages Router, Remix | Pages Router는 레거시, Remix는 Vercel 통합 미흡 |
| Next.js API Routes + Server Actions | 별도 서버 불필요, Prisma 직접 접근, 배포 단일화 | Express/Hono 별도 서버 | 이중 배포·모니터링 오버헤드, Vercel 서버리스와 부조화 |
| Prisma 7.x | 타입 안전 ORM, 자동 마이그레이션, Next.js 통합 | Drizzle, Kysely | Drizzle도 좋은 선택이나 생태계·문서·도구 성숙도에서 Prisma 우위 |
| Vitest 4.x | Vite 기반 HMR, Browser Mode, 빠른 속도 | Jest | Jest는 ESM 지원 불안정, 설정 복잡 |
| Playwright 1.60+ | 크로스 브라우저, Aria snapshots, 자동 대기 | Cypress | Cypress는 멀티탭·크로스 도메인 제약 |
| Claude Code / Codex | hooks, permissions, managed policy, MCP allowlist | Cursor, Copilot | 장기 운영에는 도구별 기능보다 공통 거버넌스가 중요 |
| Changesets | 모노레포 버전 관리 표준 | semantic-release | semantic-release는 모노레포 지원 부족 |
| React 19.2+ | use(), Compiler, Actions, useOptimistic | React 18 | 서버 컴포넌트 성숙, 새 Hook 생태계 |
| Tailwind CSS 4.1+ | CSS-first 설정, @theme, 빌드 속도 향상 | Tailwind 3 | v3 -> v4 마이그레이션 도구 제공 |
전체 참고 문헌
모노레포 기반 (Ch1-Ch4)
- Turborepo Documentation — 공식 문서
- Turborepo 2.9 — 최신 릴리스와 deprecation
- Vercel Academy: Production Monorepos — 실전 과정
- monorepo.tools — 도구 비교
- Yarn: Workspace Protocol — workspace:* 문서
- Prisma Documentation — ORM 공식 문서
- Prisma: Next.js Integration — Next.js 연동
- Node.js: Package Exports — exports 필드
앱 & 배포 (Ch5-Ch8)
- Next.js Documentation — 공식 문서
- Next.js: Multi-Zones — 멀티존
- Next.js: Route Handlers — API Routes
- Next.js: Caching — 캐싱 전략
- Next.js: Proxy — Proxy 파일 컨벤션
- Vercel: Monorepos — 모노레포 배포
- Vercel: Rolling Releases — 단계적 production rollout
- Vercel: Deployment Protection — Preview 접근 제어
- Vercel: Fluid Compute — 장기 실행 함수
- Vercel: Environment Variables — 환경 변수
- Turborepo: Pruning — turbo prune
- Turborepo: Filtering — 필터
- Changesets — 버전 관리
- Vitest: Workspace — 모노레포 테스트
- Playwright — E2E 테스트
에이전트 & 운영 (Ch9-Ch12)
- Claude Code: Memory (CLAUDE.md) — CLAUDE.md 가이드
- Claude Code: Hooks — Hooks 문서
- Claude Code: CLI Flags — CLI 실행 옵션
- OpenAI Codex: Managed configuration — 조직 정책
- OpenAI Codex: Hooks — lifecycle hooks
- skills.sh — 에이전트 스킬 매니저
- vercel-labs/agent-skills — Vercel 공식 스킬
- Vercel: Skills v1.1.1 —
npx skillsCLI - GitHub: CODEOWNERS — 코드 소유권
- Renovate — 의존성 자동 업데이트
- Sentry: Next.js — 에러 트래킹
- Vercel: Analytics — 트래픽 분석
- web.dev: Core Web Vitals — 성능 지표
추천 학습 리소스
| 유형 | 리소스 | 설명 |
|---|---|---|
| 과정 | Vercel Academy | Production Monorepos, Next.js 고급 |
| 템플릿 | Vercel Monorepo Starter | Turborepo + Next.js 스타터 |
| 레포 | vercel/turbo | Turborepo 소스코드 |
| 레포 | vercel/next.js/examples | Next.js 공식 예제 |
| 블로그 | Vercel Blog | 최신 기술 동향 |
| 커뮤니티 | Turborepo Discord | 커뮤니티 지원 |