Table of contents
- Trunk-based development: the monorepo default
- Feature branches in monorepos
- Release branches and GitFlow: when to isolate
- Tool-assisted workflows: nx and bazel
- Managing branching with Graphite
- Best practices for branching in monorepos
- Conclusion
Monorepos consolidate code for multiple projects into a single repository. This structure helps with shared dependencies, atomic commits, and unified CI workflows—but it also raises the stakes for branch management. Choosing the right branching strategy is essential to keep things stable, fast, and collaborative.
This guide explores effective branching strategies in monorepo development, covering Git workflows like trunk-based development and GitFlow, and tools like Nx, Bazel, and Graphite that enhance these strategies.
Trunk-based development: the monorepo default
Trunk-based development revolves around a single shared branch—typically main
or trunk
. Developers create short-lived feature branches that are merged back to trunk frequently, sometimes multiple times a day. The goal is rapid integration and minimal branch drift.
Monorepos thrive on this model. With many teams committing to one repo, long-lived branches quickly lead to conflicts. Instead, teams aim for atomic, incremental merges that keep trunk stable and deployable. Feature flags help ship incomplete features without disrupting production.
Google, Meta, and Shopify run their monorepos this way. For them, trunk is the only version that matters. But this model demands strong automation—especially around testing, code review, and conflict resolution.
Feature branches in monorepos
Feature branches are common in both trunk-based and GitFlow models. They isolate work in progress and support code review, but in monorepos, they must stay short-lived. With many teams pushing changes daily, stale branches become integration nightmares.
To manage complexity, many teams break up large features into small, reviewable pieces. This is where Graphite's stacked pull request model shines. You can chain PRs (e.g. Part 1 → Part 2 → Part 3), allowing parallel development and focused reviews, while still integrating changes in order.
This practice—borrowed from internal tools at Meta—has been shown to speed up reviews and reduce merge conflicts, especially in monorepos.
Release branches and GitFlow: when to isolate
In some cases, teams use GitFlow-style release branches. A release branch allows stabilization and testing before merging to main
. In monorepos, these branches should be short-lived and clearly scoped.
For example, an org might cut a release/2025-Q3
branch for a coordinated deployment of multiple apps. Critical fixes are applied directly to that branch, then cherry-picked back to trunk. This keeps production stable without slowing development.
However, long-lived branches and multiple integration targets increase overhead. Many monorepo teams use a hybrid approach: trunk-based by default, with occasional release branches for stabilization.
Tool-assisted workflows: nx and bazel
Build systems like Nx and Bazel don't define branching strategies, but they make modern workflows practical at scale.
Nx, popular in TypeScript/JavaScript monorepos, supports affected builds—only retesting apps impacted by a change. This makes frequent integration feasible even in large repos. Nx also enables dependency boundaries and ownership enforcement to reduce accidental coupling.
Teams like BetterHealthcare switched from GitFlow to trunk-based development with Nx, cutting their deployment time from hours to minutes by consolidating 40 microservices into one monorepo.
Bazel, used at Google, Uber, and Airbnb, supports high-performance builds for polyglot monorepos. Its dependency graph and caching model enable fast, incremental testing across thousands of components. Bazel pairs naturally with trunk-based workflows, supporting atomic commits without slowing teams down.
Managing branching with Graphite
Graphite focuses on the workflow layer—simplifying branching, code review, and integration. It supports:
- Stacked pull requests: Break large changes into a sequence of smaller, dependent branches.
- Merge queue: Automatically rebase, test, and merge PRs in order, keeping
main
green without manual coordination. - CLI workflows: Generate, rename, and sync branches quickly using standard conventions (e.g. ticket IDs or directory structure).
- Automation and reviewer routing: Enforce team code ownership and notify the right reviewers, especially important in shared monorepos.
Many teams use Graphite to replicate Meta's developer workflow on GitHub, but without needing a giant internal tools team. The tool is especially valuable when you have lots of parallel development, as it reduces friction in managing multiple branches and reviews across shared code.
Best practices for branching in monorepos
- Prefer trunk-based development with CI/CD, small PRs, and feature flags.
- Keep branches short-lived and rebase frequently.
- Use release branches only when needed, and merge them back quickly.
- Use stacked PRs for large features to maintain momentum and review quality.
- Automate tests and merges with tools like Nx, Bazel, and Graphite to reduce human overhead.
Conclusion
Monorepos amplify both the benefits and the risks of branching. With many teams touching shared code, your strategy must balance speed with safety. Trunk-based workflows—backed by strong tooling—offer the best path forward for most monorepo teams.
Whether you're building a monorepo from scratch or refining an existing one, tools like Graphite, Nx, and Bazel give your team the confidence to commit often, review quickly, and ship safely.