跪拜 Guibai
← All articles
Frontend

Monorepo vs Multi-Repo: The Front-End Repository Management Playbook

By 前端嘿起 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Repository architecture directly shapes build times, CI costs, and how fast a team can ship. Choosing the wrong model — or the right model without the supporting tooling — leads to version conflicts, hour-long pipelines, and onboarding friction that compounds as the codebase grows.

Summary

Front-end teams scaling beyond a single repository hit predictable pain points: bloated clone times, dependency version drift, redundant builds, and tangled release coordination. Two architectural patterns dominate the response — Monorepo and Multi-repo — each with distinct trade-offs in code sharing, build efficiency, and team autonomy. Monorepo keeps all packages in one repository with workspace-level dependency resolution and incremental builds, while Multi-repo isolates each module in its own repository for independent versioning and access control.

The tooling landscape has matured around four main options. pnpm Workspaces provide lightweight, disk-efficient package linking. Turborepo layers high-speed caching and parallel task orchestration on top. NX delivers a full-featured build system with code generation and dependency graphing. Lerna remains a focused choice for versioning and publishing workflows. Many teams combine these — pnpm plus Turborepo is a common stack — and the article walks through a complete project setup with shared TypeScript configs, cross-package aliases, and CI/CD orchestration.

Beyond tool choice, the operational practices matter just as much. Unified dependency versions, strict avoidance of circular dependencies, remote build caching, shared ESLint/Prettier configs, and automated changelog generation with Changesets all prevent the chaos that multi-repo setups can breed. A hybrid model — grouping tightly coupled packages in a Monorepo while keeping independent services in separate repos — often fits real-world team structures better than a pure approach.

Takeaways
— Single repositories become painful when clone times, IDE load, and Git operations slow down under codebase weight.
— Multi-repo setups cause dependency version drift across packages, making upgrades and debugging inconsistent.
— Monorepo keeps all packages in one repo with workspace linking, enabling direct cross-package imports without publishing to npm.
— Multi-repo isolates each module in its own repository, giving teams independent release cycles and fine-grained access control.
— pnpm Workspaces offer fast, disk-efficient package management with simple YAML-based workspace configuration.
— Turborepo adds incremental builds and remote caching, rebuilding only packages affected by a change.
— NX provides a full toolchain with code generators, dependency graph visualization, and affected-project detection.
— Lerna focuses on version bumping and publishing, supporting both independent and fixed versioning modes.
— Git Submodule and Git Subtree are native Git options for Multi-repo, but add operational complexity around updates and merges.
— Rush targets large-scale dependency management with version policies and a unified install-build-publish workflow.
— Changesets automates semantic versioning and CHANGELOG generation across multiple packages.
— Cross-repo CI/CD can be orchestrated with GitHub Actions artifacts or Jenkins Pipeline stash/unstash steps.
— A hybrid model — Monorepo for tightly coupled front-end packages, separate repos for independent services — often fits best.
— Circular dependencies break builds; extracting shared types or using event buses decouples packages safely.
— Build cache invalidation is usually caused by misconfigured output directories or missing global dependency declarations.
— Dependency version conflicts are resolved with pnpm overrides, workspace protocols, or root-level resolutions.
— Shared tsconfig, ESLint, and Prettier configs prevent drift in code style and compiler settings across packages.
— Clear directory separation into apps/ and packages/ layers keeps runnable applications distinct from shareable libraries.
— Automated dependency updates via Renovate or Dependabot reduce the manual toil of keeping versions aligned.
— Onboarding speed improves with Dockerized dev environments, architecture docs, and step-by-step setup guides.
Conclusions

Most teams don't need a pure Monorepo or pure Multi-repo; a hybrid approach that groups tightly coupled packages together while isolating independent services avoids the worst downsides of both extremes.

The real cost of Multi-repo isn't the repository count — it's the coordination tax of version alignment, cross-repo PRs, and duplicated CI pipelines that grow linearly with each new repository.

Turborepo's remote caching is an underused lever: sharing build artifacts across CI runs and developer machines can cut pipeline times by 50-80% without changing any application code.

pnpm's strict dependency resolution — where packages can't access undeclared dependencies — prevents the phantom dependency bugs that routinely break Multi-repo setups when hoisting behavior differs between environments.

Version management tools like Changesets matter more as team size grows; without automated changelogs and version bumping, release notes become fiction and breaking changes slip through unreported.

Git Submodule and Subtree are often chosen for their zero-dependency appeal, but their operational friction — forgotten updates, detached HEAD states, merge conflicts on submodule pointers — makes them a liability beyond two or three repos.

The choice between NX and Turborepo is less about features and more about philosophy: NX provides an opinionated, batteries-included framework, while Turborepo layers composably on top of your existing package manager and task runner.

Circular dependencies are a design smell that tooling can detect but not fix; the only durable solution is extracting shared contracts into a separate package that both sides depend on.

CI/CD for Multi-repo is fundamentally a graph problem — build artifacts need to flow between repositories — and most teams solve it with ad-hoc artifact uploads rather than a proper package registry, which creates reproducibility gaps.

Standardizing on a single TypeScript version and compiler options across all packages eliminates an entire class of build errors that manifest only when packages are composed together at runtime.

Concepts & terms
Monorepo
A single Git repository containing multiple projects or packages, enabling direct code sharing and unified dependency management through workspace features.
Multi-repo
An architecture where each project or module lives in its own independent Git repository, providing isolation for versioning, access control, and release cycles.
pnpm Workspace
A pnpm feature that links multiple packages within a single repository, allowing cross-package imports without publishing to npm and enforcing strict dependency boundaries.
Turborepo
A build orchestration tool by Vercel that caches task outputs and rebuilds only packages affected by code changes, dramatically speeding up CI and local development.
NX
A build system and Monorepo management tool with code generators, dependency graph visualization, and affected-project detection, offering an opinionated full toolchain.
Lerna
A tool focused on version bumping and npm publishing across multiple packages in a Monorepo, supporting both independent and fixed versioning strategies.
Git Submodule
A native Git mechanism that embeds one repository as a subdirectory inside another, maintaining a pointer to a specific commit of the child repository.
Git Subtree
A Git strategy that merges the full history of a sub-repository into a subdirectory of the main repository, making the code directly part of the parent repo.
Changesets
A tool that tracks intended version bumps and generates CHANGELOG entries, then applies them across packages in a coordinated release step.
Rush
A Microsoft-built Monorepo manager that enforces version policies, handles installation and linking, and provides a unified publish workflow for large-scale projects.
Incremental Build
A build strategy that recompiles only the code that changed and its dependents, skipping unchanged packages to reduce build times.
Remote Cache
A shared cache, often cloud-hosted, that stores build outputs so that team members and CI runners can reuse previously computed results instead of rebuilding.
Circular Dependency
A situation where Package A depends on Package B and Package B depends on Package A, causing build failures and runtime resolution errors.
Workspace Protocol
A pnpm feature (workspace:^) that links packages locally during development while resolving to the correct version range when published to a registry.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗