5 apps en un solo repositorio: el monorepo Turborepo de un desarrollador independiente
Cómo montar un monorepo con Turborepo para gestionar varias apps y webs en un solo repositorio. Configuraciones compartidas, ahorro de builds con caché y despliegue por app, desde un enfoque práctico.
Lo esencial
Cuando construyes varias apps en solitario, las configuraciones se dispersan. Con un monorepo Turborepo compartes eslint y tsconfig desde packages, la caché de turbo evita reconstruir las apps que no cambiaron, y con --filter despliegas app por app.
En esta página
Cuando construyes apps en solitario, los repositorios se multiplican sin parar. Una app, una web, otra app... y terminas copiando y pegando la configuración de eslint cinco veces. Yo lo junté todo en un solo monorepo.
El verdadero problema son las configuraciones dispersas
Con muchos repositorios, lo que más duele no es el código sino la configuración.
- Copiar eslint, prettier y tsconfig en cada repositorio
- Cambiar una regla y tener que recorrerlos todos para actualizarla
- La UI y las utilidades compartidas son demasiado triviales para publicarlas en npm
El monorepo cambia esto por un modelo donde todo se comparte desde un solo lugar.
Estructura básica
apps/
├── web/ # 랜딩
├── blog/ # 이 블로그
├── wave/ # 오늘의 파도
└── ...
packages/
├── eslint-config/ # 공용 eslint
└── typescript-config/ # 공용 tsconfig
apps/* son los artefactos que se despliegan y packages/* es la configuración y el código que las apps comparten. El tsconfig.json de cada app simplemente hereda.
{ "extends": "@repo/typescript-config/nextjs.json" }
Ahora las reglas se corrigen en un solo sitio: packages.
La caché de turbo es la clave
El arma de verdad de Turborepo es la caché. Si las entradas de una tarea (código fuente y configuración) no cambiaron, reutiliza el resultado anterior tal cual.
turbo run build # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog # blog 앱만
Basta con declarar en turbo.json las dependencias entre tareas y sus salidas.
{
"tasks": {
"build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
}
}
A partir del segundo build, termina en segundos con "FULL TURBO".
Desplegar app por app
Aunque sea un solo repositorio, el despliegue se separa por app. Con Docker puedes usar turbo prune para recortar solo el subárbol de esa app y crear una imagen ligera.
turbo prune blog --docker # blog + 내부 의존성만 남긴 out/ 생성
Este blog también lo recorté así y lo subí a un mini PC con Docker. Esa historia la cuento en el artículo sobre self-hosting.
En resumen
apps/*= artefactos desplegables,packages/*= configuración compartida- tsconfig y eslint se gestionan por herencia desde un solo lugar
- La caché de
turboevita reconstruir las apps que no cambiaron - Despliegue por app con
--filteryprune
Si mantienes varios productos en solitario, el monorepo no es un lujo sino una herramienta de supervivencia.
Preguntas frecuentes
¿A partir de cuántas apps conviene un monorepo?
Con solo pasar de 2 ya conviene, en cuanto aparecen configuraciones compartidas (eslint, tsconfig, UI). La clave es corregir la configuración en un solo lugar y que se aplique a todas las apps.
¿No se vuelve más lento el build?
Al contrario, se vuelve más rápido. turbo cachea el resultado de las tareas cuyas entradas no cambiaron y solo reconstruye las apps modificadas.
Artículos relacionados
- 💻 Desarrollo
Crear un blog MDX con Next.js desde cero: así construí este blog
El proceso de crear con Next.js 16 App Router un blog que funciona solo con archivos Markdown, sin CMS. Estructura de carpetas, configuración de MDX y SEO, explicado con el flujo de código real.
- 💻 Desarrollo
Self-hosting en un mini PC con Docker + Cloudflare Tunnel
Cómo publicar varios servicios web de forma segura con un solo mini PC en casa. HTTPS con Cloudflare Tunnel sin abrir puertos, y todo funcionando con Docker Compose.
- ☕ Día a día
La rutina diaria de un desarrollador independiente: cómo no agotarte trabajando solo
Trabajar solo, sin jefe ni compañeros, da libertad pero agota con facilidad. Aquí está la rutina diaria y las reglas que sigo para no perder el ritmo.