System-design · Monorepo

Monorepo Interview Questions
With Answers & Code Examples

5 carefully curated Monorepo interview questions with working code examples and real interview gotchas.

Practice Interactively →← All Categories
5 questions2 beginner3 core0 advanced
Q1Beginner

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

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

A monorepo stores multiple projects/packages in a single Git repository. A polyrepo gives each project its own repo.

Monorepo advantages:

  • Atomic cross-package commits — one PR can change a shared library and all consumers simultaneously, keeping them in sync.
  • Easier large-scale refactors — rename a function across 20 packages in one commit; no cross-repo PR coordination.
  • Shared tooling — one ESLint config, one TypeScript config, one CI setup for all packages.
  • Dependency visibility — you can see exactly which packages depend on what; circular deps are detectable at the repo level.
  • Simpler DXpnpm install at root installs everything; no npm linking hacks needed.

Trade-offs:

  • CI must be smart (only build/test affected packages) — tools like Turborepo and Nx handle this.
  • Access control is coarser — everyone can see all packages. CODEOWNERS files mitigate this.
  • Repo size grows — Git history includes all packages; shallow clones help.
Practice this question →
Q2Core

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

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

Turborepo speeds up monorepo builds through content-addressed caching and parallel execution.

Caching mechanism:

  1. Before running a task, Turbo computes a hash from: source files in the package, env variables listed in turbo.json, the task's dependencies' output hashes.
  2. If a cache entry exists for that hash, Turbo replays the cached output (logs + output files) instead of running the task.
  3. Cache hits are instantaneous — CI re-runs of unchanged packages take milliseconds.
// turbo.json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],  // build deps first
      "outputs": ["dist/**"],
      "env": ["NODE_ENV"]       // include in hash
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": []
    }
  }
}

Remote cache — Turborepo can push/pull cache to Vercel Remote Cache or a self-hosted HTTP cache. First CI run populates it; all subsequent machines (and developer laptops) benefit.

Practice this question →
Q3Core

How does Nx differ from Turborepo?

💡 Hint: Nx has a plugin ecosystem, code generators, and module boundary enforcement; Turborepo is minimal and pipeline-focused

Both tools optimize monorepo task running with caching and parallelism, but they differ in scope:

TurborepoNx
FocusFast pipeline runnerFull monorepo platform
Plugin ecosystemMinimalRich (React, Angular, Node, etc.)
Code generatorsNoYes (nx generate)
Module boundariesNoYes (ESLint rules per tag)
Project graphInferredExplicit + visual graph UI
Remote cacheVercel / self-hostedNx Cloud / self-hosted
Learning curveLowHigher

Nx affected commandsnx affected:test runs tests only for packages changed since the last main branch merge, dramatically cutting CI time.

When to pick Turborepo: you want minimal config, your team already knows the toolchain, and you don't need generators or boundary enforcement.

When to pick Nx: large org, multiple frameworks, need guardrails on inter-package imports, want a visual dependency graph.

Practice this question →
Q4Beginner

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

💡 Hint: pnpm hoists deps once via hard links — saves disk space and prevents phantom dependencies vs npm/yarn workspaces

pnpm workspaces link all packages in a monorepo together so they can import each other as if they were published packages, while sharing a single node_modules store.

# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'

Why pnpm over npm/yarn workspaces:

1. Hard-link store — pnpm stores each package version once globally and hard-links into projects. A 100-package monorepo doesn't duplicate React 100 times on disk.

2. Strict dependency resolution — pnpm only allows importing packages listed in a package's own package.json. npm/yarn hoist everything, enabling "phantom dependencies" (importing a transitive dep that isn't declared — breaks when the transitive dep is removed).

3. Speed — hard links are faster to set up than copies; install times drop 2–5× vs npm on large repos.

4. Filteringpnpm --filter @org/ui build runs a command in just one package; pnpm -r build runs it across all.

Practice this question →
Q5Core

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

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

Nx lets you tag each project (e.g., scope:checkout, type:feature, type:util) and then write ESLint rules that restrict which tags can import from which.

// .eslintrc.json
"@nx/enforce-module-boundaries": ["error", {
  "depConstraints": [
    { "sourceTag": "type:feature", "onlyDependOnLibsWithTags": ["type:ui", "type:util", "type:data-access"] },
    { "sourceTag": "scope:checkout", "notDependOnLibsWithTags": ["scope:profile"] }
  ]
}]

Why this matters:

  • Prevents accidental coupling between business domains (checkout code importing profile internals).
  • Keeps the dependency graph a DAG — no cycles between feature libraries.
  • Catches violations at lint time (CI) before they become architectural debt.
  • Makes it safe to eventually extract a domain into its own repo or microfrontend — no hidden cross-domain dependencies.
Practice this question →

Other System-design Interview Topics

Rendering StrategiesCore JSType SystemReact FundamentalsFunctionsMicrofrontendsGenericsAsync JSHooksObjectsArrays'this' KeywordUtility TypesError HandlingModern JSBundle OptimizationPerformanceDOM & EventsState ManagementClasses & OOPCaching StrategiesComponent PatternsAdvanced TypesAuthenticationReact RouterFormsAdvanced PatternsFrontend SecurityConcurrent ReactServer ComponentsTestingEcosystemNetwork OptimizationCore Web VitalsBrowser APIs

Ready to practice Monorepo?

Get AI feedback on your answers, predict code output, and fix real bugs.

Start Free Practice →