--- id: wiki-2026-0508-monorepo title: Monorepo category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Mono Repo, Single Repository, Polyrepo Alternative] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [monorepo, build-system, turborepo, nx, bazel] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: turborepo-nx --- # Monorepo ## 매 한 줄 > **"매 single repo, 매 multiple project, 매 shared code, 매 atomic commit"**. Google/Meta scale 의 Bazel/Buck 의 origin. 2026 mainstream 의 Turborepo 2.x / Nx 21 / pnpm workspaces — 매 small team 도 의 monorepo 의 가능. ## 매 핵심 ### 매 benefit - **Atomic refactor**: 매 lib API change + 매 caller update 의 1 PR. - **Shared dependency**: 매 single version policy. No "diamond dep" hell. - **Code reuse**: 매 internal lib import 의 trivial. - **Unified tooling**: 매 lint, test, CI 의 1 config. ### 매 cost - **Build complexity**: 매 selective rebuild 의 essential. - **Repo size**: 매 git clone 의 slow. Sparse checkout / partial clone. - **CI scaling**: 매 every PR 의 entire repo 의 test = N/A. Affected-only. - **Access control**: 매 fine-grained permission 의 hard. ### 매 응용 1. Frontend + backend + shared types: pnpm workspaces. 2. 50+ packages, JS/TS heavy: Turborepo or Nx. 3. Polyglot (Go + Rust + TS), large: Bazel/Pants. ## 💻 패턴 ### pnpm workspace ```yaml # pnpm-workspace.yaml packages: - "apps/*" - "packages/*" ``` ```json // apps/web/package.json { "name": "@acme/web", "dependencies": { "@acme/ui": "workspace:*" } } ``` ### Turborepo pipeline ```json // turbo.json { "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**", "!.next/cache/**"] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }, "lint": {}, "dev": { "cache": false, "persistent": true } } } ``` ```bash # build only affected by changes since main turbo run build --filter=...[origin/main] ``` ### Nx affected ```bash nx affected -t build test lint --base=origin/main nx graph --affected ``` ### Remote cache (Turborepo) ```bash npx turbo login npx turbo link # pushes/pulls cache from Vercel ``` ### Shared TS config ```json // packages/tsconfig/base.json { "compilerOptions": { "target": "es2022", "module": "esnext", "moduleResolution": "bundler", "strict": true, "skipLibCheck": true } } // apps/web/tsconfig.json { "extends": "@acme/tsconfig/base.json" } ``` ### Dependency boundary (ESLint) ```json { "rules": { "@nx/enforce-module-boundaries": ["error", { "depConstraints": [ { "sourceTag": "scope:web", "onlyDependOnLibsWithTags": ["scope:web", "scope:shared"] }, { "sourceTag": "scope:api", "onlyDependOnLibsWithTags": ["scope:api", "scope:shared"] } ] }] } } ``` ### Changesets (versioning) ```bash pnpm changeset # author intent pnpm changeset version # bump versions pnpm changeset publish # publish to npm ``` ### Sparse checkout ```bash git clone --filter=blob:none --sparse https://github.com/acme/monorepo cd monorepo git sparse-checkout set apps/web packages/ui ``` ### CI: changed-files matrix ```yaml # .github/workflows/ci.yml jobs: changes: runs-on: ubuntu-latest outputs: packages: ${{ steps.filter.outputs.changes }} steps: - uses: dorny/paths-filter@v3 id: filter with: filters: | web: apps/web/** api: apps/api/** ui: packages/ui/** build: needs: changes strategy: matrix: { pkg: ${{ fromJSON(needs.changes.outputs.packages) }} } steps: - run: pnpm --filter @acme/${{ matrix.pkg }} build ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 2-5 packages, JS/TS | pnpm workspaces only | | 5-50 packages, JS/TS | Turborepo + remote cache | | 50+ packages, plugin ecosystem | Nx | | Polyglot, Google-scale | Bazel / Pants / Buck2 | **기본값**: pnpm + Turborepo (TS-heavy projects). ## 🔗 Graph - 부모: [[Source-Control]] - 응용: [[Modular-Programming]] - Adjacent: [[Bazel]] · [[Nx]] · [[Turborepo]] · [[pnpm]] ## 🤖 LLM 활용 **언제**: 매 task pipeline 의 setup, dependency graph 의 visualize, affected-only command 의 generate, package.json 의 boilerplate. **언제 X**: 매 organizational decision (mono vs poly) — Conway's law + team topology judgment. ## ❌ 안티패턴 - **No build cache**: 매 PR 의 매 full rebuild = CI cost explosion. - **Inconsistent tooling**: 매 package 의 own ESLint config = chaos. - **Cyclic package deps**: A → B → A. nx graph / turbo 의 detect. - **Ignoring affected**: 매 always full test = 매 monorepo 의 advantage 의 lose. ## 🧪 검증 / 중복 - Verified (Turborepo docs, Nx docs, "Software Engineering at Google" Ch 16, Vercel monorepo handbook 2025). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — canonical monorepo with Turborepo/Nx/pnpm patterns |