I recently got a chance to work on pretty big projects which use mono-repo architecture and because in the past I was mostly working with poly-repos I decided it might be worth sharing some observations about the pros and cons of both solutions. In this post, I decided to compare mono-repo and poly-repo from the perspective of a mobile developer, keep in mind that I’m not a DevOps, or backend developer, so my observations might be biased and do not take into account things that might be important for this kind of devs. Ok, let’s start with a short explanation.
What is Monorepo
- single repository containing multiple projects in it, grouped in most cases by directories
- also known as one-repo or uni-repo
What is Polyrepo (sometimes called multi repo)
- code is spread across multiple repositories, how many… it depends on the personal preference and project architecture, but usually, some shared libs have their own repo and each platform (frontend, backend, mobile) have also dedicated one
- also known as many-repo or multi-repo
Hybrid repository structure
- some elements are stored in the dedicated repo, and some are grouped to share the code, a good example might be backend written in Python (with a dedicated repo) and Frontend and Mobile written in JS (grouped in one repo to share code)
Ok, so we know what’s the key difference between mono-repo and poly-repo, now let’s talk about different aspects of work while using one or another.
At first, it’s important to understand differences in the probably most important and most common case, code contribution.
If we contribute to only one project, then there is actually no difference for us if we use mono-repo or poly-repo as we only create one PR anyway. Things look different if we want to make changes in more than one project, for example in mobile app and in the frontend, then we will actually have to create 2 probably very similar PR’s and wait for 2 approvals, in some cases from 2 different people. In the worst case, we will have to explain some details twice, which might be annoying. This actually might be a bottleneck for some people, who are able to work on different platforms. Another problem of poly-repo might be actually fact that one project might block another, so if we are doing changes on the backend and frontend, it’s pretty obvious that at first, we have to create a PR for the backend, wait for approval, merge and then create a PR for the frontend because at this point backend will be ready to support this change done on the frontend. That might cause the delivery time of a feature will be longer than actually needed.
While talking about the contributions, it’s also worth looking at code access and ownership.
Code Access and Ownership
Once again, everything depends on how does your team looks like. In the case of poly-repo, it’s way easier to set up different access levels for particular parts of the system for the same person. It’s also possible to hide some sensitive or confident code and give access only to a few trusted developers. Poly-repo is way more flexible, but on the other hand, it’s easier to force the same rules for everyone in the case of monorepo, also thanks to CODEOWNERS feature in GitHub you can manage access rights based on directories in the same repo, however you cannot hide any directory, every element of the repo will be at least visible for everyone who has access to this repo, and this might be a problem if your company has some valuable IP which should be protected.
We are developers and unfortunately, in many cases, we just have to fix something, surprisingly even in this case repo architecture is very important, even if you don’t track your issues using GitHub.
In the case of issue tracking, I feel like the point of view is based on developer contributions again. If there are developers working on multiple platforms at once, then mono-repo is the obvious choice in my opinion. There is no need to recreate the same issue and assign the same developer in 2 or even 3 separate repositories, then close all those tasks… a lot of redundant work, even for a project manager who likes ticking closed tasks :D. On the other hand, as the team grows, amount of issues might get pretty messy at some point and it will be simply hard to track the progress of specific platforms. In this case, it’s important to at least correctly label issues, which can help filter them and will make work easier for not only developers but also project managers. A big project is simply hard to manage and honestly, it doesn’t really matter if it’s mono-repo or poly-repo.
Ok, so we developed all planned features, fixed some bugs, sprint is ending and it’s time to release…
In the case of releases, it actually depends on what’s your plan. If all elements of the app go together and you plan to release for example backend, web, and mobile at once then mono-repo might be a good choice as you create 1 tag for all platforms. Things look different if different platforms have different release schedules. If you release for example fixes for the backend once a week and the mobile app is released once a month then those GitHub tags will quickly get messy and will not help a lot. At some point, it may turn out that you actually use tags and releases only for 1 platform which is some kind of benchmark of ‘where we are at this moment’. Talking about releases we shouldn’t forget about CI, from my experience I feel like configuring CI for a platform is easier if we use a poly-repo structure, especially if you have multiple different platforms supported, like iOS, Android, frontend, and backend. Configuring Jenkins, Circle CI or even Github Actions is easier if we configure one platform per repository. In the case of mono-repo, those tools have to base on subdirectories and there are sometimes strange problems caused by that.
There is no simple answer to the question what repo architecture should you use, as usually it depends… In my opinion it mostly depends on the team abilities, especially if people can work on multiple platforms, very important is also team size and product type, what language, or languages are used, how many platforms are supported. If multiple platforms are written using same language and have similar functionality then mono-repo might be really worth considering. If you are not convinced, then maybe hybrid might be the answer, teams working in the same language, for example web and mobile, can work together and backend devs can work on a separated repo, maybe even invisible for frontend devs if there is some sensitive IP algorithm used there. Last but not least, I noticed that working on one repo encourages collaboration and this might be really valuable for not only developers but also product and the whole company, especially now in remote era.
Ok, that’s it, I shared with you my observations about repo architecture, feel free to share your ones in the comments section below. Thank you for reading and see you next time, bye!