One Repo to Rule Them All

A monorepo contains multiple projects (applications, libraries, packages) in a single repository. Instead of separate repositories for your frontend, backend, shared libraries, and infrastructure, everything lives together with shared tooling, versioning, and CI/CD. At Nexis Limited, we use monorepos for products with multiple packages — our design system, shared utilities, and multiple applications share a single repository.

Benefits of Monorepos

  • Code sharing: Shared libraries are imported directly without publishing to a registry. Changes to a shared component are immediately available to all consuming applications.
  • Atomic changes: A single PR can update a shared library and all consuming applications together. No version coordination across repositories.
  • Consistent tooling: One ESLint config, one Prettier config, one TypeScript config, one CI pipeline for the entire codebase.
  • Simplified dependency management: One lockfile, one dependency tree, one node_modules installation. No version conflicts between packages.

Turborepo

Turborepo is a high-performance build system for JavaScript/TypeScript monorepos. Key features:

  • Remote caching: Cache build outputs and share them across team members and CI. If another developer already built a package with the same inputs, you download the cached output instead of rebuilding.
  • Parallel execution: Run tasks across packages in parallel, respecting dependency order.
  • Pipeline configuration: Define task dependencies in turbo.json — build depends on build of dependencies, test depends on build, etc.
  • Minimal configuration: Simple turbo.json configuration. Easy to add to existing projects.

Nx

Nx is a comprehensive monorepo build system with additional tooling:

  • Computation caching: Similar to Turborepo — cache task outputs locally and remotely.
  • Affected commands: Determine which projects are affected by code changes and only build/test those projects. Crucial for large monorepos where rebuilding everything is too slow.
  • Code generators: Built-in generators for creating new applications, libraries, and components with consistent structure.
  • Plugin ecosystem: First-party plugins for React, Next.js, Node.js, and more with framework-specific optimizations.
  • Dependency graph visualization: Visual representation of project dependencies in the monorepo.

Choosing Between Turborepo and Nx

  • Turborepo: Choose for simpler monorepos, when you want minimal configuration, or when you are already using Vercel. Turborepo focuses on doing one thing well — fast, cached task execution.
  • Nx: Choose for larger monorepos, when you want code generation, affected commands, and a richer plugin ecosystem. Nx provides more tooling but has a steeper learning curve.

Workspace Configuration

Package Manager Workspaces

Configure your package manager (pnpm, npm, yarn) to recognize the workspace structure. pnpm workspaces (our preference) provide strict dependency isolation and efficient disk usage through content-addressable storage.

Shared Configuration

Extract shared configuration into workspace packages:

  • @repo/eslint-config — shared ESLint configuration
  • @repo/tsconfig — shared TypeScript configuration
  • @repo/ui — shared UI component library
  • @repo/utils — shared utility functions

CI/CD for Monorepos

  • Only build what changed: Use affected commands (Nx) or Turborepo's built-in change detection to avoid rebuilding unchanged packages.
  • Remote caching: Enable remote caching so CI builds reuse cached outputs from previous runs and developer machines.
  • Parallel CI jobs: Split CI into parallel jobs per package or per task type (lint, test, build) for faster pipelines.
  • Selective deployments: Deploy only the applications that changed, not every application in the monorepo.

Common Challenges

  • Repository size: Large monorepos can slow down git operations. Use git sparse-checkout to clone only the projects you work on.
  • CI complexity: Monorepo CI needs more configuration than single-project CI. Invest in CI setup early.
  • Ownership boundaries: Use CODEOWNERS files to define ownership of different packages. Different teams can own different packages within the monorepo.

Conclusion

Monorepos simplify code sharing, dependency management, and cross-project changes. Use Turborepo for fast, minimal monorepo tooling or Nx for comprehensive monorepo management. Invest in remote caching and affected commands to keep build times fast as the monorepo grows.

Structuring your projects? Our team sets up monorepo architecture for efficient development workflows.