DEV Community

Cover image for Monorepo VS Polyrepo
Eden Ella for Bit

Posted on • Updated on

Monorepo VS Polyrepo

The question of whether to maintain your codebase as monorepo or polyrepo has become even more puzzling with the rise in popularity of micro-architecture patterns like microservices, micro frontends, and micro apps.

On the one hand, monorepos are great for cross-project code sharing, dependency management, and consistency across the codebase. On the other hand, polyrepos offer more flexibility in managing projects, dependencies, and releases, and give teams the autonomy they need to work independently.

In a way, polyrepos are the more "natural" approach for micro-architecture designs as they allow us to enjoy the benefits of small, simple and autonomous projects without the complexity of a monorepo. Unfortunately, polyrepos come with their own set of challenges, especially when it comes to managing dependencies and ensuring consistency across the codebase.

A solution that combines the best of both worlds

There's a clear need for a solution that combines the best of both worlds: the simplicity and autonomy of polyrepos with the code sharing and consistency of monorepos. This is where Bit comes in. Bit allows you to manage each component of your codebase as a standalone entity, called a "Bit component."

Bit can be integrated into existing monorepos or polyrepos, or it can be used to manage your codebase in a completely decentralized way, without the need for a repository.

The first approach transforms your repository into a fine-grained monorepo, or a composable repository/codebase. The second approach no longer requires a repository at all, as Bit components can be modified, built, versioned, and shared, independently, not coupled to any repository.

From monorepo to composable and finally to completely decentralized

Click here for a high-resolution diagram

Composable codebase: maximizing code reuse and simplifying project maintenance

To understand how a composable codebase works, let's first look at how projects are structured in a monorepo. Monorepos typically host two types of projects: libraries and apps (with 'services' included). Libraries are reusable pieces of code that are shared across multiple apps, while apps are standalone projects that use these libraries (and other dependencies).

No distinction between libs and apps in composable design

A composable codebase, on the other hand, consists only of Bit components. A Bit component is both a library and, possibly, an app (i.e, a deployable component). Unlike the common structure of a monorepo, a repository consisting of Bit components will have a simple, "flat" structure that is similar to any other composable design.

Standard Applications/Services NodeJS Libraries Bit Components
Published to NodeJS Registries No. Yes. Yes. Bit components are published to Bit Platform and possibly other registries like the NPM registry. This includes deployable components or “app components”. Bit components can be installed as standard NodeJS packages.
Deployable Yes. No. Yes. While all Bit components are published to NodeJS registries, some can also be configured to be deployed.
Source-of-Truth Project-level VCS and VCS platforms like Git and Github. Project-level VCS and VCS platforms. Either “Bit scopes” and platforms like Bit Platform or project-level VCS and VCS platforms.
Component-Specific Development Setup and Dependencies No. Development tools and config, as well as dependencies, are configured on the entire repository or a sub-directory of it. No. Development tools and config, as well as dependencies, are configured on the entire repository or a sub-directory of it. Yes. Each Bit component can have its own development setup and dependencies, completely independent of its current repository or its location inside the repository. Development environments/setups are maintained as Bit components and reused by other Bit components, across projects.

Each Bit component has its source files in its own directory and a single file to serve as its entry point or "main" file. Each Bit component consumes other Bit components via their symlink/installed instance in the node_modules directory. For example:

# An example of a composable repo

button/
    index.ts
    button.ts
my-app/
    my-app.ts
    my-app.bit-app.ts (defines 'my-app' as a deployable app component)
    index.ts
node_modules/
    @my-scope/button/
      index.js -> (symlink for type support and IntelliSense)
      button.js -> (symlink) ../../button/button.ts
      dist/
        index.js (compiled)
        button.js (compiled)
    @my-scope/my-app/
      index.js -> (symlink) ../../my-app/dist/index.ts
      my-app.js -> (symlink) ../../my-app/my-app.ts
      dist/
        index.js (compiled)
        my-app.js (compiled)
Enter fullscreen mode Exit fullscreen mode

There is no structural distinction between libraries and apps in a composable codebase. Each Bit component can be consumed by other Bit components and can consume other Bit components, regardless of their type.

This greatly simplifies your project maintenance and management. You can easily understand the relationship between components, manage dependencies, and ensure consistency across the codebase.

Furthermore, every piece of functionality in your codebase (not just utility functions and basic UI elements) is a standalone entity that can be shared, versioned, and updated independently. And the best thing is that it doesn't require additional overhead or complexity. Your code is just "naturally" shareable, reusable, and even portable.

Common issues and challenges for code sharing and reusing are no longer a concern, as Bit takes care of it all, including: dependencies, documentation, build, test, versioning, and even CI/CD.

Decentralized codebase: improving team autonomy and codebase flexibility

Collaboration when Bit scopes serve as the source-of-truth for components

A decentralized codebase is one that is not managed in a single repository but is distributed across multiple repositories or even none at all. As mentioned in the table above, when working with Bit components, you decide their source of truth. It can be a project-level repository hosted on a platform like GitHub, GitLab, or Bitbucket, or individual components hosted on the Bit platform.

Depending on your team’s workflow structure, you can choose the source of truth: either the Bit scopes where components are hosted or the project repositories where they are maintained. Choosing the Bit scopes as the source of truth allows you to manage your codebase with fine-grained access-control and build setup, over each component and unparalleled flexibility in managing your codebase.

Repositories can be created and destroyed, components can be moved around, and you can decide where they should be maintained based on your team's or ogranization's workflow and the project's requirements.

In a completely decentralized codebase, repositories are used as a disposable tool

Top comments (6)

Collapse
 
nickgrass profile image
Nick Grass

It'll be great to have a sequel article that explores the different CI solutions for each of these version-control approaches.

Collapse
 
msm8 profile image
John Brooks

Brilliant article. Thanks!

Collapse
 
ashanfernando profile image
Ashan Fernando

Great Article !!

Collapse
 
whattheportal profile image
WTP | WhatThePortal.com

Good read - any info on potential repo organization efficiency hacks is appreciated.

One day if we were to publish libs, might have to change it up a bit. Bookmarked!

Collapse
 
kevin-uehara profile image
Kevin Toshihiro Uehara

Great article explaining the concept of monorepos. Tools like NX and Turborepo offer great integration through plugins (there are several) to set up integrated or standalone monorepos. I've been using NX a lot more because it has much more support and integrations like NX Cloud for monitoring, build cache, logs, etc.

Collapse
 
faizan711 profile image
Faizan

Really nice!
Do checkout my take : medium.com/stackademic/polyrepo-vs...

All feedbacks welcomed.