Advanced5 questionsFull Guide

Monorepo Architecture (Nx vs Turborepo) — System Design Interview Guide

Understand monorepo vs polyrepo trade-offs, how Turborepo and Nx solve the scaling problem, what workspace protocols do, and when a monorepo is the right architectural choice — with the depth senior engineers need for system design interviews.

The Mental Model

A monorepo is a single Git repository containing multiple related projects — apps, libraries, design systems, and tools — each with its own package.json but all sharing tooling, CI, and version control history. Think of it as a single office building where each team has its own floor but shares the lobby, elevators, and security system. A polyrepo is each team renting their own building — full independence, but crossing the street every time they need to collaborate.

The Explanation

Monorepo vs Polyrepo

In a polyrepo, each app or library lives in its own repository. Changes to shared code require publishing a new npm package version, updating dependents, and coordinating cross-repo PRs. In a monorepo, all packages live together — atomic cross-package changes, unified CI, and shared tooling.

The Scaling Problem — Why You Need a Build Tool

A naive monorepo with 50 packages and npm run build --workspaces rebuilds everything on every change. With 100 packages this takes 20 minutes. Turborepo and Nx solve this with content-addressed caching and task graph parallelization.

Turborepo

Turborepo (by Vercel) is a high-performance build system that wraps your existing package.json scripts. It adds a task graph layer on top of npm/pnpm/yarn workspaces.

// turbo.json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"], // build dependencies first
      "outputs": ["dist/**"]   // cache these outputs
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": []
    },
    "lint": {
      "outputs": []
    }
  }
}

Remote caching: turbo run build --remote-cache stores build artifacts in the cloud (Vercel or self-hosted). If the inputs (source files + dependencies) haven't changed, the cache hit restores the output instantly — CI goes from 10 minutes to 30 seconds.

Nx

Nx (by Nrwl) is a more opinionated and feature-rich monorepo framework. It provides generators (scaffolding), executors (build/test/lint runners), a visual dependency graph, and deep integration with frameworks like Next.js, Nest.js, and Angular.

// Run only affected packages since main branch
npx nx affected --target=build --base=main

// Visualise the dependency graph
npx nx graph

Nx's affected command is its killer feature — it analyses your import graph and only rebuilds/tests packages whose source or dependencies changed. This is more precise than Turborepo's file-hash-based caching for large repositories.

Turborepo vs Nx — When to Use Which

TurborepoNx
Minimal config, wraps existing scriptsOpinionated, replaces scripts with executors
Great for JS/TS monorepos already using workspacesGreat for enterprise projects needing generators/scaffolding
Vercel remote cache built-inNx Cloud or self-hosted cache
Lower learning curveSteeper, but more power

Workspace Protocols

pnpm and Yarn Berry support workspace:* protocol — packages reference each other directly without publishing to npm. Changes in a shared library are immediately available to all consumers in the repo without a version bump.

// packages/web/package.json
{
  "dependencies": {
    "@company/ui": "workspace:*",   // always the local version
    "@company/utils": "workspace:*"
  }
}

Common Misconceptions

⚠️

Monorepos mean one deployable app — a monorepo can contain dozens of apps and libraries, each deployed independently. The repo boundary and the deployment boundary are orthogonal concerns.

⚠️

Turborepo and Nx replace package managers — they sit on top of npm/pnpm/yarn workspaces. You still need a package manager that understands workspaces; Turborepo/Nx add the smart task running layer.

⚠️

Monorepos are only for big companies — small teams with shared code (e.g., a web app and a React Native app sharing business logic) benefit significantly from a monorepo.

⚠️

Git becomes slow in a monorepo — with shallow clones, sparse checkout, and partial clones, git performance in large monorepos is manageable. GitHub/GitLab have specific monorepo optimisations.

Where You'll See This in Real Code

Google: the world's largest monorepo (billions of lines of code in a single repo). All internal tools, services, and frontends share the same codebase with a custom build system (Blaze/Bazel).

Meta: React, Jest, and dozens of related packages all live in the facebook/react monorepo — contributors can make atomic changes across packages in a single PR

Vercel: the Next.js repo itself is a Turborepo-powered monorepo — the framework, CLI, docs, and playground are all managed together

Design system teams: a component library, icons package, tokens package, and Storybook all in one monorepo — component changes, token updates, and docs are all committed together atomically

Interview Cheat Sheet

  • Monorepo: one git repo, multiple packages — shared tooling, unified CI, atomic cross-package commits
  • Polyrepo: separate repos — independent versioning, but cross-repo changes require PRs across repos
  • Turborepo: lightweight, wraps existing scripts, content-addressed cache, pipeline config in turbo.json
  • Nx: opinionated, generators + executors, `affected` command for precise change detection, visual graph
  • workspace:* — pnpm/Yarn Berry protocol to reference local packages without publishing
  • Remote cache: Turborepo (Vercel) or Nx Cloud — skip rebuilding unchanged packages in CI
  • Affected commands: only rebuild/test what changed — key to keeping CI fast at scale
💡

How to Answer in an Interview

  • 1.Frame the answer around the code-sharing problem: 'When you have shared libraries consumed by multiple apps, a monorepo makes atomic changes and unified CI possible'
  • 2.Know the difference between workspace protocols and npm publishing — workspace:* means no publishing required, but you need to publish for external consumers
  • 3.Turborepo vs Nx is a common follow-up — Turborepo is simpler and wraps existing scripts; Nx is more opinionated with generators and deeper framework integration
  • 4.Mention remote caching as the key performance feature — 'the same input hash always produces the same output, so CI can skip tasks it has already done'

Practice Questions

5 questions
#01

What is a monorepo and what are its advantages over a polyrepo setup?

EasyMonorepo PRO💡 All packages in one repo — atomic commits, easier refactors, shared tooling; trade-off is CI scale and access control
#02

How does Turborepo's caching work and what makes it fast?

EasyMonorepo PRO💡 Task outputs are hashed by inputs (files + env vars); cache hits skip execution entirely — local and remote caches both supported
#03

How does Nx differ from Turborepo?

EasyMonorepo PRO💡 Nx has a plugin ecosystem, code generators, and module boundary enforcement; Turborepo is minimal and pipeline-focused
#04

What are pnpm workspaces and why are they preferred in monorepos?

EasyMonorepo PRO💡 pnpm hoists deps once via hard links — saves disk space and prevents phantom dependencies vs npm/yarn workspaces
#05

What are module boundary rules in Nx and why do they matter?

EasyMonorepo PRO💡 ESLint rules enforced via project tags — prevents forbidden imports between domains (e.g., feature libs importing from other features)

Related Topics

Bundle Optimization (Tree Shaking, Code Splitting) — System Design Interview Guide
Advanced·8–12 Qs
Microfrontends & Module Federation — System Design Interview Guide
Senior·8–12 Qs
🎯

Can you answer these under pressure?

Reading answers is not the same as knowing them. Practice saying them out loud with AI feedback — that's what builds real interview confidence.

Practice Free →Try Output Quiz