Safeguard
DevSecOps

What is a Monorepo

A monorepo houses many projects in one repository. Learn how Google, Meta, and Microsoft use them, and the blast-radius risks security teams must manage.

Priya Mehta
DevSecOps Engineer
6 min read

A monorepo is a single version-controlled repository that holds the source code for multiple distinct projects, services, or applications, rather than splitting each one into its own repository. Google's monorepo is the most cited example: as of a 2016 paper by Potvin and Levenberg, it held roughly 2 billion lines of code across 86 terabytes of data, versioned in a single Perforce-based system serving over 25,000 engineers. Meta (then Facebook) runs a comparable setup in Mercurial with more than 15 million files. Monorepos aren't just a big-company curiosity — Babel, React, Angular, and Jest all live in monorepos on GitHub today. For security teams, the appeal and the risk are the same coin: one repository means one place to enforce policy, and one place where a single compromised dependency, leaked secret, or bad merge can touch every service the organization ships.

What Is a Monorepo, Exactly?

A monorepo is a single repository containing the code for many independently deployable projects, each typically kept in its own subdirectory with its own build target. This differs from a "big ball of mud" — a monorepo still enforces module boundaries and separate build/deploy pipelines per project; it's the version control and history that are unified, not the runtime architecture. Nx and Turborepo, two of the most widely adopted JavaScript monorepo tools, both define a monorepo as workspaces sharing one package.json-level root and one .git history, with per-package build graphs layered on top. Microsoft's Windows codebase, migrated to a single Git repo in 2017 using a custom filesystem virtualization layer (GVFS, later VFS for Git), contained about 3.5 million files and 300GB of data at the time of migration — a scale that ordinary Git could not handle without that tooling.

How Is a Monorepo Different From a Polyrepo?

A polyrepo splits each service or library into its own separate Git repository, so a "polyrepo" architecture for a 50-microservice company means 50 separate .git histories, 50 separate CI pipelines, and 50 separate places to configure branch protection and secret scanning. A monorepo collapses that into one repository with one commit history, which makes atomic cross-service changes possible — a single pull request can update a shared library and every consumer of it in the same commit. The tradeoff is operational: Google's internal tooling (Blaze, later open-sourced as Bazel in 2015) exists specifically because git status and git clone don't scale to millions of files without custom sparse-checkout and virtual filesystem layers. Uber, Twitter, and Pinterest have all published engineering blog posts between 2016 and 2020 describing the custom build-graph tooling (Buck, Pants, Bazel forks) they had to adopt to make monorepos viable at their scale.

Why Do Companies Like Google and Meta Use Monorepos?

Companies adopt monorepos primarily to make large-scale refactoring and dependency management atomic and enforceable, rather than for pure convenience. When Google needs to update a shared logging library used by 8,000 internal projects, that update happens in a single commit validated by a single CI run against the entire dependent graph — not 8,000 separate pull requests waiting on 8,000 separate teams. Meta's internal tooling (Sapling, released publicly in 2022) was built explicitly to keep this workflow fast at their repo's scale. The same logic drives smaller adoption: Vercel built Turborepo (acquired into Vercel in 2021) because frontend teams running 10-30 related Next.js apps and shared component libraries wanted one lockfile and one CI pipeline instead of dependency drift across a dozen repos.

What Security Risks Does a Monorepo Introduce?

A monorepo concentrates blast radius: a single vulnerable dependency, exposed secret, or compromised CI credential can reach every service in the organization instead of just one. When CVE-2021-44228 (Log4Shell) was disclosed on December 10, 2021, organizations running a shared logging library out of a monorepo had to determine, in hours, whether that one log4j-core version was reachable from dozens or hundreds of internal services simultaneously — a scope-of-impact question that polyrepo teams could at least triage service-by-service. Secret sprawl compounds the problem: a hardcoded credential committed to a monorepo is potentially readable by every engineer with clone access to the whole codebase, not just the two or three people on the owning team, and a single leaked CI token can grant write access to every project the pipeline touches. Overly broad CODEOWNERS or branch-protection rules are also common in monorepos precisely because configuring granular per-directory review policy across thousands of subfolders is tedious, which is how unreviewed changes to security-critical paths slip through in practice.

What Tools Do Teams Use to Manage Monorepos?

Teams manage monorepo scale with dedicated build-graph and workspace tools rather than relying on default Git and npm/pip behavior. Bazel (Google, open-sourced 2015) and Buck (Meta, open-sourced 2013, rewritten as Buck2 in 2023) compute incremental build graphs so a commit only rebuilds and retests the subset of projects actually affected by a change. On the JavaScript side, Lerna (2015), pnpm workspaces, Nx (2017), and Turborepo (2021) serve the same purpose for npm-based monorepos, using content-addressed caching to avoid rerunning unaffected builds. Microsoft's Rush, used internally for large TypeScript monorepos, adds a "phantom dependency" linter specifically to catch packages that build successfully because a different subproject happens to hoist the needed version — a bug class unique to monorepo dependency resolution. None of these tools include security scanning by default, which means dependency and secret scanning has to be layered on separately and pointed at the whole graph, not just the files touched in a given diff.

How Safeguard Helps

Safeguard is built for exactly the blast-radius problem monorepos create: when a shared library or transitive dependency turns out to be vulnerable, Safeguard's reachability analysis determines which of the dozens or hundreds of services in the repository actually call the vulnerable code path, so security teams triage the 3 services that need an emergency patch instead of the 300 that merely import the package. Griffin AI, Safeguard's agent, correlates that reachability signal with commit history and ownership metadata across the monorepo to route findings to the right team automatically rather than flooding a single security inbox. Safeguard generates and ingests SBOMs at the subproject level, giving teams a per-service dependency inventory even when everything lives in one .git history, and its auto-fix PRs open targeted, tested version bumps scoped to the affected subdirectories — not a single sprawling PR that touches every package in the repo. That combination lets teams keep the atomic-commit benefits of a monorepo without inheriting an all-or-nothing security posture.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.