Skip to main content
Back to notes

A monorepo should prove leverage, not just collect packages

A portfolio monorepo only matters if the shared system makes each app cheaper to build and easier to reason about.

A monorepo becomes expensive when teams centralize abstractions without proving where reuse pays off. Shared packages need to shorten delivery, not just tidy the repository tree.

The useful test is whether a new product surface can reuse navigation, content models, forms, tables, permissions, and release tooling without importing accidental complexity.

A healthy monorepo should make ownership easier to see. Shared packages should describe real contracts: UI primitives, typed helpers, testing presets, lint rules, and deployment assumptions that every app can actually depend on.

The failure mode is collecting packages before the product has repeated needs. That usually creates a second product inside the repo: one that exists only to maintain abstractions no app is clearly asking for.

The stronger approach is to let reuse earn its place. Keep page data local until an integration is justified. Keep app-specific code in the app until two surfaces prove the same problem exists. Keep package exports narrow enough that dependency direction stays obvious.

When the monorepo is doing its job, adding a new surface feels less like starting over and more like choosing from known building blocks with clear tradeoffs.