Introduction
The way source code is organized determines developer experience, CI/CD complexity, and team collaboration. This article compares Mono-Repo vs Multi-Repo and provides guidance on choosing the right one.

1. Multi-Repo
1.1 Model
github.com/company/
├── product-service/ (repo riêng)
├── order-service/ (repo riêng)
├── cart-service/ (repo riêng)
├── product-mfe/ (repo riêng)
├── cart-mfe/ (repo riêng)
├── shell-app/ (repo riêng)
├── shared-ui/ (repo riêng, npm package)
└── shared-types/ (repo riêng, npm package)
1.2 Advantages & Disadvantages
| Advantages | Disadvantages |
|---|---|
| Clear ownership | Shared code is difficult to manage (npm publish) |
| Independent CI/CD | Complex cross-repo changes |
| Smaller repos = fast clone | Dependency version drift |
| Fine-grained access control | Consistency is difficult to enforce |
2. Mono-Repo
2.1 Model
github.com/company/platform/
├── apps/
│ ├── shell-app/
│ ├── product-mfe/
│ ├── cart-mfe/
│ └── order-mfe/
├── services/
│ ├── product-service/
│ ├── order-service/
│ └── cart-service/
├── packages/
│ ├── shared-ui/
│ ├── shared-types/
│ └── eslint-config/
├── turbo.json / nx.json
└── package.json (workspace root)
2.2 Advantages & Disadvantages
| Advantages | Disadvantages |
|---|---|
| Shared code easily (internal packages) | Large repo → slow clone |
| Atomic cross-package changes | CI complexity (affected detection) |
| Consistent tooling & configurations | Access control coarse-grained |
| Refactoring is easy | Build time long (need caching) |
3. Decision Matrix
| Factor | Multi-Repo | Mono-Repo |
|---|---|---|
| Team size | 50+ devs, many teams | < 50 devs, few teams |
| Shared code | Less shared | Many shared packages |
| Deploy independence | ✅ Natural | ✅ With affected detection |
| Cross-cutting changes | ❌ Multiple PRs | ✅ Single PR |
| CI/CD | Simple per repo | Complex but powerful |
| Onboarding | Easy (1 service/repo) | Medium (big repo) |
4. Mono-Repo Tools
4.1 Turborepo
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"]
},
"lint": {}
}
}
# Build chỉ affected packages
turbo build --filter=...[origin/main]
# Build product-mfe và dependencies
turbo build --filter=product-mfe...
4.2 Nx
# Affected commands (chỉ build/test code thay đổi)
nx affected --target=build --base=main
nx affected --target=test --base=main
# Dependency graph
nx graph
4.3 Key Features
| Features | Turborepo | Nx |
|---|---|---|
| Affected detection | ✅ Git-based | ✅ Dependency graph |
| Remote caching | ✅ Vercel | ✅ Nx Cloud |
| Task orchestration | ✅ Pipelines | ✅ Task graph |
| Code generation | ❌ | ✅ Generators |
| Plugin ecosystem | Limited | Rich (React, Node, etc.) |
5. Code Ownership (CODEOWNERS)
# .github/CODEOWNERS
apps/product-mfe/ @team-product
apps/cart-mfe/ @team-cart
services/product-*/ @team-product
services/order-*/ @team-order
packages/shared-ui/ @team-platform
packages/shared-*/ @team-platform
turbo.json @team-platform
→ PR automatically assign reviewers based on changed files.
6. Recommendations
E-Commerce Platform (series này):
Mono-Repo (Turborepo):
├── apps/ (Shell + MFEs)
├── services/ (Microservices)
├── packages/ (shared-ui, shared-types, eslint-config)
└── infra/ (Terraform, K8s manifests)
Lý do:
- Nhiều shared code (UI, types, configs)
- Cross-cutting changes thường xuyên
- Lợi ích từ affected detection & remote caching
- Team size < 50 devs
Summary
- Multi-Repo: clear ownership, simple CI, but sharing code is difficult
- Mono-Repo: easy to share code, atomic changes, needs tooling (Turborepo/Nx)
- Use Turborepo/Nx for affected detection + remote caching
- CODEOWNERS for code ownership in mono-repo
Next article: Lesson 24: CI/CD Pipeline for Microservices & Micro Frontend