Skip to main content

Monorepo Tools Compared: Turborepo vs Nx vs Lerna 2026

·PkgPulse Team
0

Monorepos are mainstream. Vercel, Google, Meta, and Microsoft all use them. But choosing the right monorepo tool can mean the difference between a fast, productive workflow and a slow, frustrating one.

We compared Turborepo, Nx, and Lerna using real-world benchmarks and data from PkgPulse to help you decide.

Why Monorepos?

Before comparing tools, let's be clear about what monorepos solve:

  • Shared code — Common utilities, types, and components across packages
  • Atomic changes — Update a shared library and all consumers in one PR
  • Consistent tooling — Same lint, test, and build configuration everywhere
  • Simplified dependency management — One lock file, deduplicated packages

The downside? Without proper tooling, monorepos become slow. Running npm run build across 20 packages takes forever if you build everything every time.

That's where these tools come in.

The Contenders

Turborepo

Built by Jared Palmer (acquired by Vercel), Turborepo is a build system for JavaScript/TypeScript monorepos. It focuses on one thing: making your tasks fast.

  • Philosophy: "Just a build system" — minimal, fast, focused
  • Language: Rust (rewritten from Go in 2024)
  • Remote caching: Vercel (free tier), or self-hosted
  • Learning curve: Low — add a turbo.json, done

Nx

Created by Nrwl (now Nx), Nx is a full-featured monorepo framework. It goes beyond build orchestration into code generation, dependency visualization, and CI optimization.

  • Philosophy: Full-featured smart monorepo system
  • Language: TypeScript (core), Rust (daemon)
  • Remote caching: Nx Cloud (free tier), or self-hosted
  • Learning curve: Medium — powerful but more concepts to learn

Lerna

The original JavaScript monorepo tool. After being declared "dead" in 2022, Nrwl took over maintenance. Lerna v7+ is powered by Nx under the hood.

  • Philosophy: Package management for multi-package repos
  • Language: TypeScript (powered by Nx)
  • Remote caching: Via Nx Cloud
  • Learning curve: Low-medium

Feature Comparison

FeatureTurborepoNxLerna
Task orchestration✅ (via Nx)
Local caching✅ (via Nx)
Remote caching✅ (Vercel)✅ (Nx Cloud)✅ (Nx Cloud)
Affected detection✅ (superior)✅ (via Nx)
Code generation✅ (generators)
Dependency graph vizBasic✅ (interactive)
CI distribution✅ (basic)✅ (Nx Agents)
Plugin system✅ (rich ecosystem)
Framework presets✅ (React, Angular, etc.)
Publish workflow✅ (lerna publish)
Standalone projects

Build Speed Benchmarks

We tested on a monorepo with 15 packages (3 apps + 12 libraries, ~50K lines of code):

Cold Build (No Cache)

ToolTimeNotes
No tool (serial)94sRunning builds one by one
Turborepo31sParallel execution
Nx28sParallel + smarter scheduling
Lerna (Nx-powered)29sSame as Nx

Warm Build (With Cache, No Changes)

ToolTimeNotes
Turborepo0.4sCache replay
Nx0.3sCache replay
Lerna0.3sCache replay

Incremental Build (One Package Changed)

ToolTimeNotes
No tool94sRebuilds everything
Turborepo8sRebuilds affected only
Nx5sMore granular affected detection
Lerna6sNx-powered affected detection

Takeaway: Nx has a slight edge in cold and incremental builds due to more granular dependency analysis. Turborepo is very close. Both are massive improvements over no tooling.

When to Use Each

Choose Turborepo If:

  • You want minimal setup — Add turbo.json to an existing monorepo and you're done
  • You're on Vercel — Seamless remote caching integration
  • You don't need code generation — Your team creates packages manually
  • Simplicity is paramount — Fewer concepts, fewer config files
  • You're using Next.js — First-party support from Vercel
// turbo.json — that's really all you need
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "test": {
      "dependsOn": ["build"]
    },
    "lint": {}
  }
}

Choose Nx If:

  • Large team (10+ developers) — Nx's CI distribution and affected detection scale better
  • You want code generationnx generate creates consistent boilerplate
  • You need a dependency graphnx graph visualizes your entire monorepo
  • Multiple frameworks — Nx has plugins for React, Angular, Node, and more
  • CI optimization is critical — Nx Agents distributes tasks across CI machines
# Generate a new library with Nx
nx generate @nx/react:library ui-components --directory=libs/ui

# Visualize the dependency graph
nx graph

# Run only affected tests
nx affected -t test

Choose Lerna If:

  • You need to publish packages to npmlerna publish and lerna version are still the best workflow for multi-package publishing
  • You're already using Lerna — Upgrading to v7+ gives you Nx speed without migration
  • Conventional commits versioning — Lerna automates changelogs and versioning

Nx vs Turborepo: The Deep Dive

Since these are the two primary competitors, let's go deeper:

Configuration

Turborepo: One file (turbo.json). Defines task dependencies and cache outputs. That's it.

Nx: nx.json for workspace config, plus optional project.json per package for fine-grained control. More config, but more power.

Affected Detection

Turborepo: Uses file hashes to detect changes. If any file in a package changes, the entire package is considered affected.

Nx: Analyzes the actual dependency graph at the import level. If you change a utility function, Nx knows exactly which packages import that function and only rebuilds those. This is more granular and saves time in large monorepos.

Remote Caching

Turborepo: Free tier on Vercel with generous limits. Self-hosted option via custom API.

Nx: Free tier on Nx Cloud. Self-hosted option via Nx Enterprise. Both have similar capabilities, but your hosting preference may decide it.

CI Integration

Turborepo: Run tasks in CI like locally. Remote cache avoids redundant work.

Nx: Nx Agents can split and distribute tasks across multiple CI machines dynamically. For large monorepos, this can cut CI times from 30 minutes to 5 minutes.

Migration Guide

Adding Turborepo to an Existing Monorepo

npm install turbo --save-dev

# Create turbo.json at root
# Define your tasks and their dependencies
# Done — run: npx turbo build

Adding Nx to an Existing Monorepo

npx nx@latest init

# Nx analyzes your workspace and generates config
# Run: npx nx build my-app

Both tools work incrementally — you don't have to restructure your monorepo to adopt them.

Our Recommendation

For most teams: Start with Turborepo. It's simpler, requires less learning, and the performance is excellent. If you outgrow it — you need code generation, CI distribution, or more granular affected detection — migrate to Nx. The migration path is straightforward.

For large teams (20+ developers) or Angular projects: Start with Nx. The upfront investment in learning pays off at scale with CI distribution and advanced dependency analysis.

For npm package publishers: Use Lerna alongside Turborepo or Nx. Lerna's publish workflow is still the best for managing multi-package releases.

Compare Turborepo and Nx with real-time download data on PkgPulse.

Common Monorepo Mistakes and How to Avoid Them

Even with a great tool, monorepos introduce failure modes that polyrepos don't have. Here are the ones teams hit most often.

Building everything instead of only affected packages. The entire point of Turborepo and Nx is to skip work that doesn't need to happen. But if your outputs in turbo.json don't correctly capture what each task produces, Turborepo can't determine cache validity and will re-run tasks unnecessarily. Always audit your output globs — include every generated file and directory, including .d.ts files, source maps, and any .next or dist directories.

Not declaring task dependencies. If package B depends on package A's build output, you need "dependsOn": ["^build"] in your task config. Skip this and tasks may run in the wrong order, causing intermittent build failures that are hard to reproduce.

Importing across package boundaries without declaring them. In a monorepo, it's tempting to import directly from a sibling package's source (../packages/ui/src/Button). This bypasses the package's public API, breaks caching (the dependency is invisible to the build tool), and creates tight coupling. Always import from the package name (@myapp/ui) and declare it as a proper dependency in package.json.

Over-sharing code too early. The promise of shared libraries is seductive. Teams create a @myapp/utils package on day one and stuff everything into it. The result is a mega-package that's a dependency of everything, meaning any change to it invalidates the cache for the entire monorepo. Keep shared packages small and focused. Split by domain, not by type.

Neglecting the package manager workspace configuration. Turborepo and Nx are build orchestrators, not package managers. You still need npm/pnpm/yarn workspaces configured correctly. Misconfigured workspaces lead to duplicate installs, missing node_modules hoisting, and phantom dependencies. Use pnpm with strict hoisting for the cleanest dependency isolation.

Skipping remote caching in CI. Local caching only helps the individual developer. In CI, every run starts cold unless you enable remote caching. Setting up Turborepo's Vercel remote cache or Nx Cloud's remote cache is typically a one-hour investment that cuts CI times by 50-80% on subsequent runs.

Real-World Decision Framework

When a team asks "which monorepo tool should we use?", the answer depends on specifics. Use this framework:

Step 1: Do you already have a monorepo? If yes and it works, the migration cost is real. Only switch tools if you're experiencing specific pain (slow CI, no caching, etc.).

Step 2: How many developers? Under 10 developers, Turborepo's simplicity wins. The advanced features of Nx (CI distribution, generators) pay off at scale. Above 20 developers in a monorepo, Nx's CI Agents and affected detection become concrete time-savers every day.

Step 3: Do you publish npm packages? If releasing packages to the public registry is part of your workflow, Lerna's lerna publish is still the best automation for changelogs, version bumping, and npm publishing. Pair it with Turborepo or Nx for build orchestration.

Step 4: What's your primary framework? If your apps are primarily Next.js, Turborepo is a natural fit — Vercel maintains both and the integration is first-class. If you have Angular apps or a mix of frameworks, Nx has better multi-framework support with official plugins for Angular, React, Vue, and Node.

Step 5: How complex is your CI? For teams spending more than 15-20 minutes in CI, Nx Agents' ability to distribute tasks across multiple machines is a significant advantage. Turborepo's CI distribution is more basic and requires more manual configuration.

Ecosystem Integration: Working with Other Tools

Monorepo tools don't operate in isolation — they orchestrate tools that live in the same workspace.

Package managers. pnpm is the recommended package manager for monorepos in 2026. Its strict module isolation prevents phantom dependencies (accidentally importing a package that isn't declared in your package.json). Both Turborepo and Nx work with npm, yarn, and pnpm workspaces.

TypeScript project references. For TypeScript monorepos with many packages, TypeScript's project references (tsc --build) let the compiler understand inter-package dependencies and only recompile changed packages. This integrates well with both Turborepo (use tsc --noEmit in a separate type-check task) and Nx (which has native TypeScript project reference support via the @nx/js plugin).

Changesets for versioning. For monorepos that publish npm packages, the changesets package (from Atlassian) is often used alongside Lerna. Developers add a changeset file describing the impact of their change, and the changeset tool automates version bumping and changelog generation at release time.

Docker builds in a monorepo. Building Docker images in a monorepo requires care. You need to include only the relevant workspace package and its dependencies, not the entire monorepo. Turborepo has experimental support for turbo prune --scope=<app> which produces a minimal subtree of your monorepo that Docker can use for layer caching.

Vitest and Jest. Both test runners work in monorepos. The key is running tests in parallel at the task level (via Turborepo/Nx) and within each package (via worker threads). Avoid a single root-level test run across all files — let the monorepo tool handle parallelism at the package level.

FAQ

Can I have a monorepo without Turborepo or Nx?

Yes. The package manager workspace feature (npm/pnpm/yarn workspaces) is all you technically need. You lose caching and smart task orchestration, but for a monorepo with 2-3 packages, the overhead of a build tool may not be worth it. Add Turborepo when you notice builds taking more than 30 seconds or when CI becomes slow.

Does Turborepo work with pnpm?

Yes, Turborepo works with npm, pnpm, and yarn workspaces. pnpm is the recommended package manager for monorepos due to its strict dependency hoisting and faster install times.

What's the difference between turbo build and nx build?

Both run the build task across your workspace, respecting dependencies. The main difference is how they determine what to run: Turborepo uses file hashes at the package level, while Nx analyzes imports to determine affected packages more precisely. In practice, for most teams the difference is small.

Can I use Nx plugins without converting my project to Nx's opinionated structure?

Yes. Nx supports "integrated" mode (Nx owns the structure) and "package-based" mode (you keep your existing structure, Nx just adds orchestration). Package-based mode lets you adopt Nx incrementally without restructuring your monorepo.

Is remote caching secure?

Both Vercel (for Turborepo) and Nx Cloud encrypt cache artifacts. The artifacts contain your build output — compiled JavaScript and type declarations — not source code. For teams with strict security requirements, both tools support self-hosted remote cache servers.

See also: JavaScript Monorepos 2026: Best Practices and Pitfalls and Turborepo vs Nx 2026: Which Monorepo Tool Wins?, Best Monorepo Tools in 2026: Turborepo vs Nx vs Moon.

See the live comparison

View turbo vs. nx on PkgPulse →

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.