Monorepo vs Polyrepo: Como Organizar tus Proyectos
Una guía práctica para decidir la mejor estrategia de organización de repositorios para tu equipo y proyecto.
Introducción: La decisión arquitectónica invisible
La forma en que organizas tus repositorios de código tiene un impacto profundo en la productividad de tu equipo, la velocidad de desarrollo, la calidad del código y la facilidad de mantenimiento. Es una decisión que afecta a cada desarrollador cada día, pero que raramente se discute con la profundidad que merece.
Existen dos enfoques principales: monorepo (todo el código en un solo repositorio) y polyrepo (un repositorio por proyecto o servicio). Empresas como Google, Meta, Microsoft y Uber usan monorepos a escala masiva, mientras que la mayoría de startups y proyectos open source operan con polyrepos. Ambos enfoques tienen méritos, y la elección correcta depende de factores específicos de tu organización.
En los últimos años, la herramienta para monorepos ha mejorado dramáticamente. Turborepo, Nx y pnpm workspaces han eliminado muchas de las desventajas históricas de los monorepos, haciendo que este enfoque sea viable para equipos de todos los tamaños. En este artículo, analizaremos ambos enfoques en profundidad y te daremos un marco de decisión práctico.
¿Qué es un monorepo?
Un monorepo (mono-repositorio) es un único repositorio de Git que contiene múltiples proyectos, paquetes o servicios. No debe confundirse con un monolito: un monorepo puede contener múltiples aplicaciones independientes, librerías compartidas, servicios backend, y herramientas de infraestructura, todos versionados y gestionados juntos.
Un monorepo típico de una startup podría contener: la aplicación web frontend (React/Next.js), la API backend (Node.js/Python), librerías compartidas (tipos TypeScript, utilidades, componentes UI), la aplicación móvil (React Native), herramientas de CLI internas, y configuración de infraestructura (Terraform, Docker). Todo en un solo repositorio con un historial de Git unificado.
Estructura típica
La estructura más común organiza los proyectos en directorios apps/ (aplicaciones desplegables) y packages/ (librerías compartidas). Cada sub-proyecto tiene su propio package.json, configuración de TypeScript y tests, pero comparten dependencias raíz, configuración de linters, y el pipeline de CI/CD.
Las dependencias entre paquetes del monorepo se resuelven localmente mediante workspaces (de pnpm, yarn o npm), lo que significa que los cambios en una librería compartida se reflejan instantáneamente en las aplicaciones que la consumen, sin necesidad de publicar a npm ni actualizar versiones manualmente.
Herramientas para monorepos en 2026
Turborepo (Vercel)
Turborepo es la herramienta de monorepo más popular en el ecosistema JavaScript/TypeScript. Adquirida por Vercel en 2021, se ha convertido en el estándar para monorepos de aplicaciones web. Su principal innovación es el sistema de caché remoto: los resultados de builds, tests y lints se cachean y comparten entre desarrolladores y CI, eliminando trabajo redundante.
Turborepo analiza el grafo de dependencias de tu monorepo y ejecuta las tareas en el orden correcto, paralelizando todo lo que es posible paralelizar. Si cambias un paquete que solo afecta a dos de tus diez aplicaciones, Turborepo solo reconstruye esas dos aplicaciones y sus dependencias, no todo el monorepo. Esto reduce los tiempos de CI de horas a minutos.
La configuración es mínima: un archivo turbo.json en la raíz define las tareas (build, test, lint) y sus dependencias. Turborepo se integra nativamente con pnpm workspaces, yarn workspaces y npm workspaces, y funciona con cualquier framework JavaScript.
Nx
Nx es una herramienta más completa y opinionada que Turborepo. Ofrece generadores de código (scaffolding), un grafo de dependencias visual, affected commands (solo ejecuta tareas en proyectos afectados por un cambio), y plugins para frameworks populares (React, Angular, NestJS, Next.js). Nx es especialmente potente para monorepos grandes con decenas o cientos de proyectos.
Nx Cloud proporciona caché remoto distribuido similar a Turborepo, y Nx Console ofrece una interfaz visual en VS Code para navegar y gestionar el monorepo. La desventaja es que Nx es más complejo de configurar y tiene una curva de aprendizaje más pronunciada que Turborepo.
Nx también soporta múltiples lenguajes (no solo JavaScript/TypeScript), lo que lo hace adecuado para monorepos políglotas que incluyen Go, Python, Rust o Java junto con aplicaciones web.
pnpm workspaces
pnpm workspaces es la funcionalidad nativa de pnpm para gestionar monorepos. A diferencia de npm o yarn, pnpm usa un almacén de contenido global con enlaces duros (hard links), lo que significa que las dependencias compartidas entre proyectos del monorepo se almacenan una sola vez en disco. Esto ahorra significativamente espacio y acelera las instalaciones.
pnpm workspaces se configura añadiendo un campo workspaces en el package.json raíz que indica los directorios de los sub-proyectos. Las dependencias entre paquetes del workspace se resuelven automáticamente, y pnpm garantiza el aislamiento de dependencias: cada paquete solo puede acceder a las dependencias que declara explícitamente, previniendo el "phantom dependency" problem que afecta a npm y yarn.
Para muchos equipos, la combinación de pnpm workspaces + Turborepo es el stack ideal: pnpm gestiona las dependencias de forma eficiente y Turborepo gestiona la ejecución de tareas con caching inteligente.
Ventajas del monorepo
Código compartido sin fricción: Las librerías compartidas (tipos TypeScript, componentes UI, utilidades) se consumen directamente del monorepo sin necesidad de publicar a npm. Los cambios en una librería compartida se propagan instantáneamente a todos los consumidores, y puedes verificar que ningún consumidor se rompe antes de mergear el cambio.
Atomicidad de cambios: Un cambio que afecta a múltiples proyectos (añadir un campo a la API y actualizar el frontend que lo consume) se hace en un solo commit y un solo pull request. En polyrepo, necesitarías coordinar PRs en múltiples repositorios, con el riesgo de que queden desincronizados.
Configuración unificada: ESLint, TypeScript, Prettier, Jest y la configuración de CI/CD se definen una vez en la raíz y se heredan en todos los sub-proyectos. Esto garantiza consistencia y elimina la deriva de configuración que ocurre cuando cada repositorio evoluciona independientemente.
Visibilidad y descubribilidad: Todo el código está en un solo lugar. Los desarrolladores pueden explorar, entender y contribuir a cualquier proyecto sin necesidad de clonar múltiples repositorios. Esto fomenta la colaboración entre equipos y reduce los silos de conocimiento.
Refactorización a gran escala: Renombrar una interfaz que se usa en 20 proyectos es trivial en un monorepo: cambias la definición y todas las referencias en un solo commit. En polyrepo, necesitarías actualizar cada repositorio individualmente y coordinar los despliegues.
Desventajas del monorepo
Repositorio grande: Con el tiempo, el monorepo crece en tamaño y el historial de Git se vuelve pesado. Operaciones como git clone, git log y git blame se vuelven más lentas. Herramientas como git sparse-checkout y git shallow clone mitigan este problema, pero añaden complejidad.
CI/CD complejo: El pipeline de CI debe ser inteligente para solo construir y testear los proyectos afectados por un cambio. Sin herramientas como Turborepo o Nx, cada commit ejecutaría todos los tests de todos los proyectos, lo que es inviable para monorepos grandes.
Permisos y acceso: En un monorepo, todos los desarrolladores tienen acceso a todo el código. Si necesitas restringir el acceso a ciertos proyectos (por compliance, seguridad o razones organizativas), un monorepo no es la mejor opción. GitHub y GitLab no ofrecen permisos granulares a nivel de directorio.
Acoplamiento accidental: La facilidad de importar código entre proyectos puede llevar a acoplamiento no deseado. Un desarrollador puede importar una función interna de otro proyecto sin darse cuenta de que no era una API pública. Herramientas como Nx ofrecen boundary rules para prevenir este tipo de acoplamiento.
Curva de aprendizaje: Los nuevos desarrolladores necesitan entender la estructura del monorepo, las herramientas de build y las convenciones de organización. Esto puede ser abrumador inicialmente, especialmente en monorepos grandes con cientos de paquetes.
¿Qué es un polyrepo?
Un polyrepo (multi-repositorio) es la estrategia tradicional donde cada proyecto, servicio o librería tiene su propio repositorio de Git independiente. Es el enfoque por defecto y el más común en la industria, especialmente en proyectos open source y organizaciones pequeñas.
Ventajas del polyrepo
Simplicidad: Cada repositorio es independiente, con su propia configuración, dependencias y pipeline de CI/CD. No necesitas herramientas especiales ni entender la estructura de un monorepo. Git funciona de forma estándar y todas las operaciones son rápidas.
Permisos granulares: Puedes dar acceso a cada repositorio de forma independiente. Esto es esencial cuando diferentes equipos gestionan diferentes servicios y no todos deben tener acceso a todo el código.
Independencia de despliegue: Cada servicio se despliega de forma completamente independiente, con su propio ciclo de release. Un equipo puede desplegar su servicio varias veces al día mientras otro despliega semanalmente, sin interferencias.
Libertad tecnológica: Cada repositorio puede usar diferentes lenguajes, frameworks y herramientas sin restricciones. Un servicio en Go, otro en Python y otro en Node.js coexisten sin problemas de configuración compartida.
Desventajas del polyrepo
Código compartido difícil: Las librerías compartidas deben publicarse a un registry (npm, PyPI) y versionarse semánticamente. Los cambios breaking requieren coordinar actualizaciones en todos los consumidores, lo que puede tardar semanas o meses. Muchos equipos terminan con versiones desactualizadas de librerías internas porque el proceso de actualización es demasiado costoso.
Cambios cross-repo: Un cambio que afecta a múltiples repositorios (cambiar un contrato de API entre frontend y backend) requiere múltiples PRs coordinados, con el riesgo de que se desplieguen en orden incorrecto y causen downtime.
Deriva de configuración: Cada repositorio tiende a divergir en configuración de linters, formatters, versiones de TypeScript y estructura de tests. Con el tiempo, mantener la consistencia entre 20 repositorios se convierte en un trabajo de tiempo completo.
Onboarding fragmentado: Un nuevo desarrollador necesita clonar, configurar y entender múltiples repositorios para ser productivo. Cada repo tiene sus propias instrucciones de setup, variables de entorno y dependencias de sistema.
Cuándo usar monorepo
El monorepo es ideal cuando: tienes múltiples proyectos que comparten código significativamente (tipos, componentes, utilidades), tu equipo es de tamaño pequeño a mediano (hasta 50-100 desarrolladores), usas principalmente un lenguaje/ecosistema (JavaScript/TypeScript), valoras la consistencia de configuración y tooling, y los proyectos evolucionan juntos con cambios cross-project frecuentes.
Los monorepos son especialmente productivos para: productos con frontend + backend + app móvil que comparten tipos y lógica, organizaciones que mantienen múltiples aplicaciones web con un design system compartido, y equipos que practican trunk-based development y despliegue continuo.
Cuándo usar polyrepo
El polyrepo es ideal cuando: tus servicios son verdaderamente independientes con poco código compartido, diferentes equipos gestionan servicios diferentes con autonomía completa, necesitas permisos de acceso granulares por repositorio, usas múltiples lenguajes y ecosistemas sin relación, o tus servicios tienen ciclos de release completamente independientes.
Los polyrepos son especialmente apropiados para: organizaciones grandes con equipos autónomos que gestionan microservicios independientes, proyectos open source donde cada librería tiene su propia comunidad de contribuidores, y consultoras que gestionan proyectos para clientes diferentes que no deben mezclarse.
Estrategias de migración
De polyrepo a monorepo
La migración de múltiples repositorios a un monorepo se puede hacer de forma incremental. Empieza creando la estructura del monorepo con Turborepo o Nx, luego migra los proyectos uno por uno usando git subtree o herramientas como git-repo-merge que preservan el historial de commits. Prioriza migrar primero las librerías compartidas y luego las aplicaciones que las consumen.
Un enfoque pragmático es no preservar el historial completo de Git (que puede ser enorme y ralentizar el clone) y empezar con un historial limpio en el monorepo, archivando los repositorios antiguos como referencia. La mayoría de equipos encuentran que el historial antiguo pierde relevancia rápidamente después de la migración.
De monorepo a polyrepo
La migración inversa es menos común pero a veces necesaria (por ejemplo, cuando un proyecto crece y necesita independencia). Usa git filter-branch o git filter-repo para extraer un subdirectorio como un repositorio independiente con su historial preservado. Planifica cuidadosamente la separación de dependencias compartidas y la migración del pipeline de CI/CD.
Conclusión
No hay una respuesta universal. El monorepo con Turborepo/pnpm workspaces es la tendencia dominante en el ecosistema JavaScript/TypeScript para equipos que construyen productos con frontend y backend, y ofrece ventajas significativas en productividad y consistencia. Sin embargo, el polyrepo sigue siendo la opción correcta para organizaciones con servicios verdaderamente independientes, equipos autónomos y necesidades de permisos granulares.
Si estás empezando un proyecto nuevo con frontend, backend y librerías compartidas, nuestra recomendación es empezar con un monorepo usando pnpm workspaces + Turborepo. La inversión inicial en configuración es mínima (menos de una hora) y los beneficios se acumulan desde el primer día. Si en el futuro necesitas separar proyectos, siempre puedes extraerlos a repositorios independientes.