Articles

What Is a Monorepo? Single-Repository Development Explained

A monorepo holds multiple projects in one repository with shared tooling and atomic commits. How it compares to splitting projects across separate repos.

Takina Takina · · 4 min read
Code editor with dark theme showing project files

A monorepo is a single repository that holds multiple distinct projects or packages, versioned and built together, instead of splitting each one into its own repository. A company might keep its web app, API server, shared component library, and internal tooling all in one repo rather than four separate ones. The opposite approach — one repository per project — is usually called a polyrepo.

What actually goes in a monorepo

A monorepo isn’t just “a big repo” — it’s typically organized as a workspace of packages, each with its own manifest and dependencies, but sharing a single version history and a single place to run tooling. A typical layout separates apps (deployable things, like a web frontend or API) from packages (shared libraries, like a design system or a set of utility functions consumed by multiple apps). Package managers across ecosystems support this pattern through native workspace features, and dedicated build tools add task orchestration and caching on top so that changing one package doesn’t force rebuilding everything downstream of it unnecessarily.

Why teams choose this structure

Atomic cross-project changes. If a shared library and the three apps that consume it all live in one repo, a single commit can update the library and all its consumers together. In a polyrepo setup, the same change means coordinating a release of the library, then separate pull requests in every consuming repo, often waiting on version bumps to propagate.

Shared tooling and configuration. Linting rules, formatting, CI pipelines, and build configuration live in one place instead of being copied — and slowly drifting — across many repos.

Easier code sharing. Extracting a shared utility into its own package is a much smaller step when it’s just a new folder in the same repo, rather than a whole new repository with its own release process.

Consistent semantic versioning decisions. Related packages can be versioned together deliberately, rather than each repo’s maintainers making independent judgment calls about what counts as a breaking change.

The costs that come with it

None of this is free. As a monorepo grows, so does the cost of naive tooling: cloning the whole history, running every test on every change, or type-checking the entire codebase for a one-line fix all get slower without investment in caching and selective execution. Git operations like rebasing or merging touch a much larger, more actively-changing history than they would in a smaller, focused repo. And because everything lives together, a broken build in one package can, if CI isn’t scoped carefully, block merges across the whole organization rather than just the affected project.

Runtime choice matters here too — the difference between Bun and Node in install and script execution speed compounds noticeably at monorepo scale, where a single install might resolve dependencies for dozens of packages at once. The same is true in other ecosystems — a fast package manager like the ones covered in our uv piece matters more, not less, as the number of packages managed together grows.

Monorepo vs polyrepo

MonorepoPolyrepo
Cross-project changesAtomic, single commitCoordinated across repos and releases
Shared tooling/configCentralizedDuplicated or synced manually
Code sharingLow frictionRequires publishing and versioning
Build/CI complexityNeeds caching and scoping to stay fastNaturally scoped per repo
Access control granularityCoarser (often whole-repo)Per-repo, more granular
OnboardingOne clone gets everythingClone only what’s relevant

Type checking and shared types

One underrated benefit shows up specifically in TypeScript codebases: when a frontend and its API live in the same repo, the types describing a request or response can be shared directly rather than duplicated on both sides or published as a separate package. A change to a shared type surfaces as a type error in every consumer immediately, at compile time, rather than as a runtime mismatch discovered after two separately-versioned repos drift out of sync. That tight feedback loop is one of the more concrete, everyday arguments for a monorepo, beyond the higher-level organizational tradeoffs.

Which one fits

Monorepos tend to pay off most for teams with several interdependent projects that change together often — a shared design system consumed by multiple products is the textbook case. Polyrepos tend to fit better when projects are genuinely independent, owned by different teams with little code sharing, or need separate access control. Plenty of organizations land somewhere in between: a few related products in one monorepo, with truly standalone tools kept separate.

The takeaway

A monorepo trades the isolation of separate repositories for atomic cross-project changes, shared tooling, and lower-friction code sharing — at the cost of needing real investment in build caching and scoped CI once it grows past a handful of packages. It’s not a universal upgrade over a polyrepo; it’s a structural bet that your projects change together often enough that shared history and shared tooling outweigh the overhead of a larger, more complex repository.

Takina Takina · · 4 min read

What Is a Lockfile? Reproducible Dependency Installs

A lockfile records the exact dependency versions your package manager resolved, so every install — from your laptop to CI — reproduces the same tree.

#JavaScript #Web Development #Developer Tools
Takina Takina · · 4 min read

JavaScript Intl API: Formatting Dates and Numbers

The Intl API formats dates, numbers, and currency using a user's locale without a library. How Intl.DateTimeFormat and Intl.NumberFormat work.

#JavaScript #Web Development #Developer Tools
Takina Takina · · 5 min read

Turbopack vs Webpack: Choosing a JS Bundler

Turbopack is a Rust-based bundler built for incremental speed; Webpack is the mature, plugin-heavy standard. How they differ and when to pick each.

#JavaScript #Web Development #Developer Tools