Skip to main content

Monorepo Tools Compared: Turborepo vs Nx vs Lerna in 2026

·PkgPulse Team

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.

See the live comparison

View turbo vs. nx on PkgPulse →

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.