---
name: cachely-monorepo-migration
description: Migrate existing repositories into a monorepo with a task runner (Nx or Turborepo) and remote caching from day one. Use when consolidating repos, importing a project into a monorepo, or restructuring a single repo into cached, graph-aware projects.
---

# Migrating to a monorepo

A safe migration is incremental: move one project at a time, keep every
project releasable throughout, and enable remote caching before the first
project lands so CI never regresses.

## 1. Prepare the workspace

Create the workspace with the task runner you chose (see the
`cachely-monorepo-evaluation` skill if undecided):

```sh
# Nx
npx create-nx-workspace@latest acme --preset=npm
# Turborepo
npx create-turbo@latest acme
```

Wire the remote cache immediately - a warm cache is what keeps CI fast while
project count grows. Create a workspace token at https://app.cachely.dev and
configure the tool per the `cachely-remote-cache` skill (env vars for
Nx/Turborepo; `settings.gradle` or `.bazelrc` for JVM/Bazel builds).

## 2. Import projects one at a time

Per project, in order of fewest dependencies first:

1. Import with history when the tool supports it (`nx import <repo-url>`),
   or `git subtree add` to preserve history manually.
2. Give it a `package.json`/`project.json` with real `build`, `test`, `lint`
   scripts - the task runner drives these.
3. Declare internal dependencies explicitly (workspace `dependencies` on the
   shared packages) so the task graph and cache hashing see the edges.
4. Replace registry-published internal packages with workspace references.
5. Verify: `nx build <project>` / `turbo run build --filter=<pkg>` passes,
   and a second run is a cache hit.

Keep the old repository read-only (not deleted) until the imported project
has shipped from the monorepo at least once.

## 3. Converge CI

Replace per-repo pipelines with one pipeline that scopes to changes:

```sh
nx affected -t lint test build      # Nx
turbo run lint test build --affected # Turborepo
```

Provide the cache token as a CI secret (see the `cachely-ci-setup` skill).
The first pipeline run is cold; every later run reuses work from any machine.

## 4. Pitfalls

- **Do not merge projects into one giant build** - keep them separate graph
  nodes or affected detection and caching lose their value.
- **Implicit coupling**: tasks that read sibling projects' files without a
  declared dependency produce stale cache hits. Declare the edge.
- **Non-cacheable tasks from day one**: fix tasks that write outside their
  output dirs or depend on undeclared env vars as you import them (see the
  `cachely-enable-task-caching` skill), not after.
- **Lockfile unification**: expect one dependency-resolution pass; pin
  versions where upgrades are unsafe and schedule the rest.
