After this lesson, you will be able to: Explain what monorepos solve, when to use one, and how tools like Turborepo and pnpm workspaces make them practical.
Monorepos host multiple packages, services, or apps in one Git repository. Used at Google, Facebook, Microsoft, Stripe, Vercel. Tools like Turborepo make the pattern accessible to small teams in 2026.
Polyrepo: one Git repo per project / library / service. Independent versioning, independent CI, independent ownership. The default. Monorepo: many projects in one Git repo. Shared tooling, atomic cross-project changes, easier refactoring, harder build performance. Neither is universally better. Polyrepo wins for small teams with few cross-project changes. Monorepo wins for organizations with shared internal libraries, design systems, or multiple deploy targets.
/apps/web, the main Next.js application. /apps/admin, an internal admin tool. /apps/marketing, the marketing site. /packages/ui, shared React components used by all three apps. /packages/config, shared ESLint / Prettier / tsconfig. /packages/db, shared Prisma schema and client. All in one Git repo. Changes that touch a shared package + an app are one atomic commit, reviewed in one PR.
Turborepo runs your tasks in dependency order and caches outputs. Free, made by Vercel.
// turbo.json (in the monorepo root){"$schema": "https://turborepo.com/schema.json","tasks": {"build": {"dependsOn": ["^build"],"outputs": [".next/**", "!.next/cache/**", "dist/**"]},"lint": {},"test": { "dependsOn": ["^build"] },"dev": { "cache": false, "persistent": true }}}// Run all builds in dependency order (packages/ui builds before apps/web):// turbo run build// Run only what changed since main, plus its dependents:// turbo run build --filter='[origin/main]'// Subsequent runs use the cache; unchanged packages return in milliseconds.
pnpm is the most monorepo-friendly Node package manager. Free, fast, disk-efficient.
# pnpm-workspace.yaml at the repo rootpackages:- 'apps/*'- 'packages/*'# apps/web/package.json depends on a shared package:{"name": "@acme/web","dependencies": {"@acme/ui": "workspace:*","@acme/db": "workspace:*"}}# Install once at the root:# pnpm install# Add a dep to a specific package:# pnpm add react -F @acme/web# Run a script across all packages:# pnpm -r run test
Small project with one app and no shared libraries. Monorepo overhead exceeds the benefit. Multiple completely independent products with no shared code. There's nothing to monorepo. Team uses incompatible tooling per project (different language runtimes, different deploy systems). Mixing them in one repo creates more pain than it solves. The rule of thumb: monorepo when you have at least 2 apps sharing at least 1 internal library, and a team that benefits from atomic cross-project changes.
Turning every repo into a monorepo because it's trendy. The overhead is real. Skipping the build orchestrator (Turborepo, Nx). Without it, `npm run build` at the root rebuilds everything every time. Treating shared packages as 'too important to touch'. The point of a monorepo is that you CAN modify packages/ui in the same PR as apps/web. Mixing Yarn / npm / pnpm. Pick one for the whole repo; mixing them produces lockfile chaos. Forgetting that monorepo CI must understand which projects changed. Run only the affected jobs (Turborepo's `--filter` handles this).
Pick the most honest answer.
Sign in and purchase access to unlock this lesson.