Monorepo vs. Polyrepo: compromisos reales
El debate del monorepo no es sobre herramientas — es sobre cómo tu equipo se comunica, despliega y comparte código entre los límites de los proyectos.

Toda organización de ingeniería en crecimiento eventualmente se enfrenta a la pregunta del monorepo. ¿Un repositorio grande para todo, o muchos repositorios pequeños — uno por servicio o librería? La respuesta no es universal, y adoptar cualquiera de los dos enfoques sin entender los compromisos lleva a sufrimiento.
Qué significa realmente cada enfoque
Un monorepo almacena múltiples proyectos en un solo repositorio. Un polyrepo le da a cada proyecto su propio repositorio. La distinción importa para la gestión de dependencias, el diseño del pipeline de CI y la colaboración entre equipos.
# Monorepo structure
my-company/
├── apps/
│ ├── web/ # Next.js frontend
│ ├── api/ # Express backend
│ └── admin/ # Admin dashboard
├── packages/
│ ├── ui/ # Shared component library
│ ├── utils/ # Shared utilities
│ └── config/ # Shared configs (ESLint, TS)
├── package.json
└── turbo.json
# Polyrepo structure
my-company-web/ # Own repo, own CI, own deps
my-company-api/ # Own repo, own CI, own deps
my-company-admin/ # Own repo, own CI, own deps
my-company-ui-lib/ # Published to npm registry
my-company-utils/ # Published to npm registry
Dónde ganan los monorepos
Cambios atómicos entre proyectos
Cuando una librería compartida cambia su API, el monorepo te permite actualizar a todos los consumidores en un solo commit.
// ❌ Polyrepo: changing a shared library's API requires coordinated releases
// 1. Update ui-lib, bump version, publish to npm
// 2. Update web app, install new version, fix breaking changes
// 3. Update admin app, install new version, fix breaking changes
// 4. Hope nothing breaks between steps 1 and 3
// ✅ Monorepo: one PR updates the library and all consumers
// packages/ui/src/Button.tsx — change the prop interface
// apps/web/src/pages/Home.tsx — update usage
// apps/admin/src/pages/Dashboard.tsx — update usage
// All in one commit, one CI run, one reviewConfiguración compartida
// Monorepo root package.json
{
"private": true,
"workspaces": ["apps/*", "packages/*"],
"devDependencies": {
"typescript": "^5.3.0",
"eslint": "^8.56.0",
"prettier": "^3.2.0"
}
}Una versión de TypeScript, una config de ESLint, una config de Prettier. Sin drift entre proyectos.
Descubrimiento de código
En un monorepo, buscar todos los usos de una función funciona con un solo grep. En un polyrepo, necesitas buscar a través de múltiples repositorios — y quizás no sepas cuáles usan un paquete determinado.
Dónde ganan los polyrepos
Despliegue y escalado independientes
# ❌ Monorepo CI — any change triggers checks for everything
# (unless you invest heavily in affected-project detection)
on:
push:
branches: [main]
jobs:
test-all:
runs-on: ubuntu-latest
steps:
- run: npm test --workspaces # Tests everything
# ✅ Polyrepo CI — only the changed service is tested and deployed
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test # Tests only this service
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- run: npm run deploy # Deploys only this serviceAutonomía de equipo
Los polyrepos les dan a los equipos control total sobre sus elecciones de tecnología, pipelines de CI y cadencias de release. El equipo A puede usar Vitest mientras el equipo B usa Jest. El equipo C puede desplegar cada hora mientras el equipo D despliega semanalmente.
Tooling más simple
Los monorepos requieren herramientas especializadas (Turborepo, Nx, Lerna, Bazel) para manejar builds incrementales, cacheo de tareas y detección de proyectos afectados. Los polyrepos funcionan con tooling estándar desde el primer momento.
El impuesto de las herramientas de build
Los monorepos solo funcionan bien con una orquestación de build adecuada. Sin ella, los tiempos de CI crecen linealmente con el tamaño del código.
// turbo.json — Turborepo task pipeline
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["build"]
},
"lint": {},
"typecheck": {
"dependsOn": ["^build"]
}
}
}# Only build and test projects affected by the current changes
turbo run build test --filter=...[HEAD~1]Sin cacheo y detección de proyectos afectados, un monorepo con 20 paquetes se vuelve dolorosamente lento. Esta inversión en tooling es el costo real de los monorepos.
Marco de decisión
| Factor | Monorepo | Polyrepo |
|---|---|---|
| Tamaño del equipo | < 50 ingenieros | > 50 o múltiples equipos autónomos |
| Código compartido | Mucho compartir entre proyectos | Poco compartir entre proyectos |
| Cadencia de despliegue | Similar entre proyectos | Muy distinta por equipo |
| Stack tecnológico | Mayormente homogéneo | Diverso (distintos lenguajes) |
| Inversión en tooling | Dispuesto a aprender Turborepo/Nx | Quiere Git + CI estándar |
El enfoque híbrido también es válido: un monorepo para servicios estrechamente relacionados que comparten código, con repos separados para sistemas independientes.
Errores comunes
// ❌ Monorepo anti-pattern: circular dependencies
// packages/auth imports from packages/user
// packages/user imports from packages/auth
// Build order becomes impossible to resolve
// ✅ Extract shared types into a separate package
// packages/shared-types — no dependencies on other packages
// packages/auth — depends on shared-types
// packages/user — depends on shared-typesEn los polyrepos, el error equivalente es acoplar fuertemente los servicios mediante acceso compartido a la base de datos o cadenas de APIs síncronas que podrían haber sido un solo servicio.
Puntos clave
- Los monorepos habilitan cambios atómicos en librerías compartidas y todos sus consumidores
- Los polyrepos les dan autonomía a los equipos sobre el tooling, el CI y la cadencia de despliegue
- Los monorepos requieren inversión en herramientas de build — sin Turborepo o Nx, los tiempos de CI se vuelven insoportables
- Los polyrepos requieren infraestructura de registry para compartir librerías entre repositorios
- Elige según la estructura de tu equipo y los patrones de compartir código, no según las modas


