Turborepo가 해결하려는 문제
Turborepo 공식 문서를 보면 이런 말이 나온다.
"Turborepo is a high-performance build system for JavaScript and TypeScript codebases."
핵심 기능은 세 가지다.
| 기능 | 설명 |
|---|---|
| 로컬/리모트 캐싱 | 변경 없는 패키지는 빌드 스킵 |
| 병렬 실행 | 의존성 없는 태스크 동시 실행 |
| 증분 빌드 | 변경된 패키지만 다시 빌드 |
대규모 모노레포에서 빌드 시간이 대폭 단축되는 사례가 많다. 팀원 간 리모트 캐시를 공유하면 CI 비용도 절감된다.
근데 나는 그 규모가 아니다
pixelDiff의 현실을 보자.
pixelDiff/
├── apps/web # Next.js 웹앱
├── extension # Chrome 확장
├── packages/core # 공유 유틸리티
├── packages/api-contracts # API 타입
└── packages/scripts # DB 스크립트
패키지 3개, 앱 2개. CI 기준 전체 빌드에 약 2분. 그 중 Next.js 빌드가 대부분이다.
솔직히 말하면:
- 캐싱? web 코드를 건드리면 어차피 web 빌드가 돌아간다. 그게 2분 중 대부분이다
- 리모트 캐시? 혼자 개발하는데 누구와 공유하나
- 병렬 실행 최적화? 패키지 3개에서 의미 없다
Turborepo가 자랑하는 핵심 기능들이 이 규모에서는 "있으면 좋은" 정도였다.
그럼에도 모노레포를 선택한 이유
Turborepo의 캐싱이 아니라, 모노레포 구조 자체가 해결해주는 문제가 있었다.
혼자서 프론트엔드, 백엔드, 인프라를 다 만지는 상황. 가장 비싼 비용은 빌드 시간이 아니라 컨텍스트 스위칭이었다.
레포가 분리되어 있다고 가정해보자.
프론트 작업 중
→ API 응답 타입 바꿔야 함
→ 백엔드 레포 열기
→ 타입 수정, npm publish << 좀 과장해서 (타입을 패키지로 관리했다고 가정)
→ 프론트 레포로 돌아와서 npm install
→ "아 뭐하고 있었지?"
모노레포에서는:
프론트 작업 중
→ 옆 폴더 열어서 타입 수정
→ 바로 import해서 확인
→ 끝
팀이 있으면 역할이 나뉜다. 백엔드 담당자가 API를 관리하고, 프론트 담당자가 UI를 관리한다. 컨텍스트가 분산된다.
혼자 하면 모든 컨텍스트가 내 머릿속에 있어야 한다. 모노레포는 그 머릿속을 물리적으로 한 폴더에 모아주는 것이다.
실제로 체감한 것들
타입 변경이 즉시 반영된다
api-contracts 패키지에 API 응답 타입을 Zod 스키마로 정의해뒀다.
// packages/api-contracts/src/projects/schemas.ts
export const ProjectSchema = z.object({
id: z.string(),
name: z.string(),
devUrl: z.string(),
// ...
});
이걸 apps/web의 API route와 프론트 컴포넌트에서 둘 다 import한다.
스키마를 수정하는 순간, API route에서 타입 에러가 뜨고, 프론트 컴포넌트에서도 타입 에러가 뜬다. "배포했는데 타입 안 맞음" 사고가 구조적으로 막힌다.
원자적 커밋이 가능하다
API 엔드포인트를 바꾸면 프론트 호출부도 같이 바꿔야 한다. 모노레포에서는 이게 한 커밋이다.
fix:[all] 프로젝트 상태 API 응답 구조 변경
- api-contracts: ProjectState 스키마 수정
- web/api: 응답 형식 변경
- web/components: 호출부 수정
레포가 분리되어 있으면 "백엔드 먼저 배포하고, 프론트 나중에 배포"라는 순서를 관리해야 한다. 혼자 하면 이거 실수하기 쉽다.
전체 검색이 진짜 전체 검색이다
"이 함수 어디서 쓰지?" → Cmd+Shift+F 한 번이면 프론트, 백엔드, extension 전부 나온다.
레포가 나뉘어 있으면 각각 열어서 검색해야 한다. 사소해 보이지만, 하루에 수십 번 하는 동작이다.
Turborepo는 대규모 모노레포의 빌드 최적화를 위해 만들어졌다. 나는 그 규모가 아니다.
그래도 괜찮다. 도구의 본래 목적과 내 사용 목적이 다를 수 있다.
pnpm workspace로 모노레포 구조를 잡으면서 Turborepo를 얹는 건 거의 공짜다. turbo.json 파일 하나 추가하면 끝이다. 캐싱이 당장 필요 없어도, 나중에 프로젝트가 커지면 그때 효과를 볼 수 있다.
핵심은 Turborepo가 아니라 모노레포 구조 자체다. 혼자 개발할 때 컨텍스트 스위칭을 줄여주고, 타입 동기화를 강제하고, 원자적 커밋을 가능하게 해준다.
"이 규모에서 모노레포가 필요할까?"라는 질문에 대한 내 답은: 캐싱 때문이 아니라 흐름을 유지하기 위해 필요하다.
프런트엔드 엔지니어, QA 엔지니어 그리고 디자이너를 위한
" ALL IN ONE " QA 서비스
https://pixeldiff.turtle-tail.com
'FrontEnd' 카테고리의 다른 글
| DPR(Device Pixel Ratio) 고해상도 이미지 처리 (0) | 2026.03.21 |
|---|---|
| Spring Physics로 오뚜기 애니메이션 구현하기 (0) | 2026.03.10 |
| shadcn/ui 도입기: Headless UI로 컴포넌트 제어권 되찾기 (0) | 2026.02.24 |
| Marquee Selection (범위 선택) 구현하기 (0) | 2026.02.21 |
| Pixi.js 다중 선택 드래그 구현하기 (0) | 2026.02.19 |
