ADR 006: Turborepo para orquestacion del monorepo

Estado: Aceptado Fecha: 2025-03-15

Contexto

Nuestro monorepo (platform-core) contiene 7+ paquetes (design system, tipos compartidos, utils, configuraciones). Necesitamos una herramienta para orquestar tareas de build/test/lint entre paquetes con orden de dependencias correcto, caching y CI rapido.

Decision

Usar Turborepo (turbo@^2.8.10) para orquestacion de tareas y caching en el monorepo.

Turborepo Turborepo Positivo Config simple con turbo.json Cache content-addressable Cache remoto Builds incrementales Negativo Menos funcionalidades que Nx Cache vinculado a Vercel Sin soporte polyrepo

Consecuencias

Positivas

  • Configuracion simple: un unico turbo.json define el pipeline de tareas
  • Caching content-addressable: omite tareas cuando los inputs no han cambiado
  • Cache remoto (Vercel o self-hosted): cache de CI compartida entre desarrolladores y ejecuciones de CI
  • Entiende el grafo de dependencias de paquetes: ejecuta tareas en orden topologico correcto
  • Builds incrementales: solo reconstruye los paquetes modificados y sus dependientes
  • Rapido: escrito en Rust, overhead minimo
  • Flag --filter para apuntar a paquetes especificos
  • Se integra de forma natural con pnpm workspaces
  • Curva de aprendizaje baja para los desarrolladores

Negativas

  • Menos rico en funcionalidades que Nx (sin generacion de codigo, sin visualizacion del grafo de dependencias, sin herramientas de migracion)
  • Cache remoto vinculado a cuenta de Vercel (o self-host)
  • Sin soporte integrado para gestion de polyrepos (solo gestiona el monorepo)
  • Ecosistema de plugins limitado en comparacion con Nx
  • Sin deteccion de affected/changed para PRs (depende de --filter o --since manuales)

Configuracion de cache remoto

Proveedor de cache

El cache remoto de Turborepo se configura usando Vercel Remote Cache como proveedor principal. Existen alternativas self-hosted (p.ej., turborepo-remote-cache en Docker, Ducktape) si no se desea hosting en Vercel, pero la opcion gestionada por Vercel se recomienda por simplicidad y fiabilidad.

  • Vercel Remote Cache: Se habilita vinculando el repositorio a un team de Vercel via turbo login y turbo link. Una vez vinculado, los artefactos de cache se suben y descargan automaticamente desde el CDN de Vercel.
  • Opcion self-hosted: Para organizaciones que requieren residencia de datos o control on-premise, turborepo-remote-cache puede desplegarse como servidor HTTP independiente respaldado por almacenamiento compatible con S3. Las variables de entorno TURBO_API, TURBO_TEAM y TURBO_TOKEN configuran el endpoint personalizado.

Firma de cache

Para prevenir envenenamiento de cache y asegurar la integridad de los artefactos, la firma de cache esta habilitada:

  • Configurar TURBO_REMOTE_CACHE_SIGNATURE_KEY con un secreto compartido (minimo 32 caracteres) en entornos de CI y locales.
  • Cuando esta habilitado, Turborepo firma cada artefacto antes de subirlo y verifica la firma al descargarlo. Cualquier artefacto manipulado se rechaza y la tarea se re-ejecuta.
  • Rotar la clave de firma periodicamente (recomendado: cada 90 dias) y actualizarla en todos los pipelines de CI y entornos de desarrollo simultaneamente.

Configuracion de comparticion por equipo

  • Todos los desarrolladores del equipo se autentican via turbo login usando su cuenta de Vercel (vinculada al team).
  • La variable de entorno TURBO_TEAM (o el flag --team) asegura que los artefactos esten en el namespace correcto del equipo, previniendo colisiones de cache entre equipos.
  • Los pipelines de CI usan un service token (TURBO_TOKEN) con acceso de escritura para subir artefactos de cache. Las maquinas de los desarrolladores tienen acceso de lectura-escritura por defecto tras vincular.
  • TTL de cache: Vercel remote cache retiene artefactos durante 7 dias por defecto. Los artefactos mas antiguos se eliminan automaticamente, manteniendo el uso de almacenamiento predecible.

Alternativas consideradas

Nx

Mas rico en funcionalidades (generadores de codigo, UI de grafo de dependencias, comando affected, plugins para muchos frameworks). Pero: setup mas pesado, curva de aprendizaje mas pronunciada, genera mas archivos de configuracion. El enfoque nx.json + project.json por paquete es mas complejo. Excesivo para un monorepo solo de librerias con 7 paquetes. Mejor adaptado para monorepos que tambien contienen aplicaciones.

Lerna

Herramienta legacy, ahora mantenida por Nx. Lerna por si solo es una herramienta de publicacion, no un task runner. Usar Lerna + Nx es efectivamente usar solo Nx. Sin caching sin Nx.

Solo scripts de npm/pnpm

Sin caching, sin ejecucion de tareas consciente de dependencias, sin optimizacion de paralelismo. Aceptable para <3 paquetes, se descompone a escala.

Bazel

Sistema de build extremadamente potente con caching de grano fino. Pero: curva de aprendizaje masiva, setup complejo, no disenado para flujos de trabajo JavaScript-first. Excesivo para el tamano de este proyecto.

Moon

Herramienta de monorepo mas nueva basada en Rust. Prometedora pero menos madura, comunidad mas reducida, menos probada en produccion.