Organizing Large Frontend Repositories: Studio Monorepos vs Polyrepos

Team 6 min read

#architecture

#monorepo

#polyrepo

#frontend

#webdev

Introduction

Large frontend organizations wrestle with how to structure code, dependencies, and CI pipelines across many apps, packages, and teams. Two dominant patterns emerge: studio monorepos, where multiple apps and libraries live in a single repository, and polyrepos, where each app or domain exists in its own repository. This post compares the approaches, outlines typical trade-offs, and offers practical guidance for choosing and evolving your strategy.

What is a Studio Monorepo?

A studio monorepo is a single repository that contains multiple frontend applications and shared libraries. It uses a workspace toolchain (for example, Nx, Turborepo, or yarn/pnpm workspaces) to manage dependencies, build pipelines, and tests across packages. Benefits include:

  • Unified tooling and consistent conventions
  • Easy cross-package code sharing and refactoring
  • Centralized updates for design systems and core utilities
  • Efficient end-to-end caching and selective builds

Challenges often involve repository size, onboarding friction for new contributors, and the complexity of configuring robust CI/CD to avoid unnecessary work when unrelated packages change.

What is a Polyrepo?

A polyrepo approach gives each app or domain its own repository (and often its own CI). Shared components or design systems may live in separate repos or as published packages. Benefits include:

  • Clear ownership and autonomy for teams
  • Simpler onboarding for new contributors to a single app
  • Faster iteration cycles within a single repo scope
  • Independent versioning and release cadences

Trade-offs include fragmented cross-cutting changes, duplication of shared logic or UI, and the overhead of coordinating updates across repos.

Core Trade-offs

  • Coordination vs autonomy: Monorepos excel at cross-cutting changes; polyrepos excel at team autonomy.
  • Code reuse vs duplication: Monorepos encourage shared libs; polyrepos risk duplication unless you publish and version shared packages.
  • Tooling complexity: Monorepos require robust workspace tooling and caching; polyrepos require robust release and dependency management.
  • CI/CD efficiency: Monorepos can benefit from project-wide affected commands; polyrepos require per-repo optimization and may need cross-repo integration tests.

When to Choose a Studio Monorepo

  • Strong cross-team code reuse: design systems, component libraries, utilities used by many apps.
  • Frequent coordinated changes: updates to shared APIs, theming, or accessibility APIs that should propagate consistently.
  • Unified release strategy: you want to ship multiple apps with synchronized changes or a single source of truth for dependencies.
  • Centralized governance: you benefit from a single governance model and consistent linting, testing, and security scans.

Best practices:

  • Start with a clear package/layout strategy (apps/, libs/, tools/).
  • Use a modern workspace tool (Nx, Turborepo, or similar) with robust caching.
  • Implement strict boundaries between apps and libs, with explicit public APIs for shared packages.
  • Invest in a scalable CI plan that uses affected builds and tests to limit workload.
  • Provide onboarding programs and mentorship to help new contributors navigate the monorepo.

When to Choose Polyrepos

  • Independent teams with distinct lifecycles: teams own their CI, deployments, and roadmaps.
  • Minimal cross-team coupling: limited need for shared code or centralized design systems.
  • Clear ownership and autonomy are priorities: smaller, simpler repo boundaries reduce cross-repo coordination overhead.
  • You’re not ready to invest in heavy monorepo tooling or governance now.

Best practices:

  • Create a central, versioned design system or shared components as publishable packages (internal npm packages, for example) with stable APIs.
  • Establish strong contributor guidelines for when and how to update shared packages.
  • Use automated release tooling to coordinate cross-repo updates when shared components evolve.
  • Align testing strategies across repos, including contract tests for public interfaces.

Migration Patterns: From Polyrepo to Monorepo

  • Start with a staged consolidation: collect two or three closely related apps into a single workspace, introducing isolated libs for shared components.
  • Use a gradual migration plan: leave apps in their repos while slowly moving shared libraries into the monorepo, published as internal packages if needed.
  • Establish governance early: define versioning policies, API surface rules, and deprecation paths for shared packages.
  • Leverage tooling for incremental changes: tools that support path mappings, isolated builds, and caching reduce the pain of migration.
  • Maintain compatibility: ensure existing CI and test suites continue to pass during transition, and provide deprecation warnings for migrated APIs.

Migration Patterns: From Monorepo to Polyrepo

  • Identify natural boundaries: domain or app boundaries that benefit from autonomy and independent lifecycles.
  • Extract shared libs into publishable packages: ensure stable APIs and semantic versioning to minimize breaking changes.
  • Create a migration plan for teams: minimize disruption by phasing reorganization and updating CI/CD gradually.
  • Maintain a single source of truth for design decisions: even in polyrepos, a central guide for UX, branding, and accessibility helps maintain consistency.

Tooling and Build Strategies

  • Monorepo tooling: Nx, Turborepo, Bazel, or PNPM workspaces offer:
    • A highlighted benefit: affected builds/tests, caching, and shared task pipelines.
    • Challenges: config complexity, learning curve, and potential over-optimization needs.
  • Polyrepo tooling: efficient per-repo CI pipelines, conventional publish workflows, and mono-channel updates for shared packages.
    • Challenges: cross-repo version alignment, coordinated releases, and increased overhead for sharing updates.

Best practices:

  • Choose a tool worthy of your core needs: if cross-app changes are common, monorepo tooling is valuable; otherwise, polyrepo tooling with solid internal package management may suffice.
  • Standardize on a common set of conventions: lint rules, formatting, test suites, and type checking to reduce drift across repos or packages.
  • Invest in robust dependency management: for monorepos, optimize workspace layouts; for polyrepos, ensure reliable internal package publishing and versioning.

Governance, CI/CD, and Quality

  • Monorepos benefit from centralized governance and cross-cutting checks (security, accessibility, performance) applied uniformly.
  • Polyrepos require cross-repo coordination leadership, with stable API contracts and clear deprecation timelines.
  • In both patterns, establish a baseline of tests (unit, integration, visual regression) and enforce them consistently.
  • Use automated checks for dependencies and license compliance to maintain health across the codebase.

Organization and Developer Experience

  • Monorepos reduce duplication and enable faster refactors but can overwhelm newcomers with complexity.
  • Polyrepos offer simpler mental models per repo but demand discipline to keep shared components in sync.
  • Invest in comprehensive onboarding, documentation, and a strong internal component library to improve DX regardless of pattern.

Conclusion

There is no one-size-fits-all answer. Studio monorepos shine when teams share a lot of code, want centralized governance, and can invest in a robust toolchain. Polyrepos excel when teams want autonomy, simpler scope per repo, and straightforward release rhythms. The most effective approach often starts with a hybrid mindset: a core monorepo for shared components and common tooling, plus polyrepos for high-autonomy apps that don’t require tight cross-team coordination. Regularly re-evaluate team needs, tooling maturity, and deployment realities, and adjust your structure accordingly.