ADR 006: Turborepo for Monorepo Orchestration
Status: Accepted Date: 2025-03-15
Context
Our monorepo (platform-core) contains 7+ packages (design system, shared types, utils, configs). We need a tool to orchestrate build/test/lint tasks across packages with proper dependency ordering, caching, and fast CI.
Decision
Use Turborepo (turbo@^2.8.10) for task orchestration and caching in the monorepo.
Consequences
Positive
- Simple configuration: single
turbo.jsondefines task pipeline - Content-addressable caching: skips tasks when inputs haven't changed
- Remote caching (Vercel or self-hosted): CI cache shared across developers and CI runs
- Understands package dependency graph: runs tasks in correct topological order
- Incremental builds: only rebuilds changed packages and their dependents
- Fast: written in Rust, minimal overhead
--filterflag for targeting specific packages- Integrates seamlessly with pnpm workspaces
- Low learning curve for developers
Negative
- Less feature-rich than Nx (no code generation, no dependency graph visualization, no migration tools)
- Remote caching tied to Vercel account (or self-host)
- No built-in support for polyrepo management (only manages the monorepo)
- Limited plugin ecosystem compared to Nx
- No affected/changed detection for PRs (relies on manual --filter or --since)
Remote Cache Configuration
Cache Provider
Turborepo remote caching is configured using the Vercel Remote Cache as the primary provider. Self-hosted alternatives (e.g., turborepo-remote-cache on Docker, Ducktape) are available if Vercel hosting is not desired, but the Vercel-managed option is recommended for simplicity and reliability.
- Vercel Remote Cache: Enabled by linking the repository to a Vercel team via
turbo loginandturbo link. Once linked, cache artifacts are automatically uploaded and downloaded from Vercel's CDN. - Self-hosted option: For organizations that require data residency or on-premise control,
turborepo-remote-cachecan be deployed as a standalone HTTP server backed by S3-compatible storage. TheTURBO_API,TURBO_TEAM, andTURBO_TOKENenvironment variables configure the custom endpoint.
Cache Signing
To prevent cache poisoning and ensure artifact integrity, cache signing is enabled:
- Set
TURBO_REMOTE_CACHE_SIGNATURE_KEYto a shared secret (minimum 32 characters) in CI and local environments. - When enabled, Turborepo signs each artifact before upload and verifies the signature on download. Any tampered artifact is rejected and the task re-executes.
- Rotate the signing key periodically (recommended: every 90 days) and update it in all CI pipelines and developer environments simultaneously.
Team Sharing Configuration
- All developers on the team authenticate via
turbo loginusing their Vercel account (linked to the team). - The
TURBO_TEAMenvironment variable (or--teamflag) ensures artifacts are scoped to the correct team namespace, preventing cross-team cache collisions. - CI pipelines use a service token (
TURBO_TOKEN) with write access to push cache artifacts. Developer machines have read-write access by default after linking. - Cache TTL: Vercel remote cache retains artifacts for 7 days by default. Older artifacts are evicted automatically, keeping storage usage predictable.
Alternatives Considered
Nx
More feature-rich (code generators, dependency graph UI, affected command, plugins for many frameworks). But: heavier setup, steeper learning curve, generates more config files. The nx.json + project.json per package approach is more complex. Overkill for a library-only monorepo with 7 packages. Better suited for monorepos that also contain applications.
Lerna
Legacy tool, now maintained by Nx. Lerna alone is a publishing tool, not a task runner. Using Lerna + Nx is effectively just using Nx. No caching without Nx.
npm/pnpm scripts only
No caching, no dependency-aware task execution, no parallelism optimization. Fine for <3 packages, breaks down at scale.
Bazel
Extremely powerful build system with fine-grained caching. But: massive learning curve, complex setup, not designed for JavaScript-first workflows. Overkill for this project size.
Moon
Newer Rust-based monorepo tool. Promising but less mature, smaller community, less proven in production.