Where Does the Code Live?
While not strictly a branching strategy, the decision of how to organize your repositories fundamentally shapes your workflow, your tooling requirements, and how your branching strategy plays out in practice.
1. The Monorepo (Monolithic Repository)
All code for your entire organization — frontend, backend, mobile apps, infrastructure, shared libraries — lives in one single Git repository.
- Pros:
- Atomic cross-service changes: A single commit can update an API endpoint and the frontend that calls it simultaneously. No coordinating PRs across repos.
- Easy code sharing: Shared libraries are just folders. No versioning, no publishing to a package registry.
- Unified tooling and standards: One CI pipeline, one linting config, one place to enforce security policies.
-
Visibility: Any developer can see and contribute to any part of the codebase.
-
Cons:
- Scale challenges: Git was not designed for repositories with millions of files. Commands like
git statusandgit logslow to a crawl. Google's internal monorepo requires custom-built version control tooling (Piper) because Git cannot handle it. - Build complexity: You cannot naively rebuild everything on every commit. You need smart build tools (Bazel, Nx, Turborepo) that understand dependency graphs and only rebuild what changed.
- Access control: Git's native access control is all-or-nothing per repository. Restricting which teams can modify which folders requires additional tooling (CODEOWNERS files, custom CI checks).
2. The Polyrepo (Multiple Repositories)
Every service or project gets its own separate Git repository. This is the default for most organizations and the model GitHub itself encourages.
- Pros:
- Simplicity at small scale: Each repo is small, fast, and independently manageable.
- Team autonomy: Each team owns their repo and can choose their own workflows, dependencies, and release cadence.
-
Clear boundaries: Repository boundaries enforce service boundaries, which aligns well with microservices architecture.
-
Cons:
- Dependency management overhead: Shared code must be versioned and published as packages (npm, PyPI, Maven). Updating a shared library requires publishing a new version and then updating every consumer repo separately.
- Cross-service changes are painful: A change that touches three services requires three PRs, three code reviews, and careful coordination to deploy in the right order.
- Tooling fragmentation: Each repo may drift toward different standards, dependency versions, and CI configurations over time.
The emerging middle ground: Some organizations use a "many-repo" approach with monorepo tooling — multiple repositories, but with tools like Nx or Turborepo that understand cross-repo dependencies and can orchestrate builds across them. This attempts to capture the autonomy of polyrepo with some of the atomic-change benefits of monorepo.
If asked "Monorepo or Polyrepo?" in an interview, never give a one-word answer. The correct response is: "It depends on team size, service coupling, and build tooling maturity." Then demonstrate you understand the trade-offs: monorepos require investment in build tooling to remain fast at scale; polyrepos require investment in dependency management and cross-repo coordination tooling. The question is which problem you'd rather solve.