Monorepos: Proposing a Monorepo to your team (Q&A)
Tags: learning, architecture, software, monorepo
Published: 2024-06-13 09:01:26

This post follows a demo I did for my team leaders, where I explained what a monorepo is and how it could address the problems we are currently facing with web frontend dev. TODO insert link
The team leaders include a mix of senior developers and business analysists. So some questions are more technical and some are more general. The questions are in no particular order.

{% details How would a monorepo address the issue of one app being dependent on components from another, potentially causing coupling and making updates to the dependent app more difficult? %}
There shouldn't be a scenario where apps are dependent on another. Application modules should be a minimal as possible and import feature libraries where all the heavy lifting is done. The feature, which exists outside the application, in a shared space, can then be imported into different applications.
{% enddetails %}

{% details How do you decide what's shared and what's not? "*I don’t want anyone using my stuff*" %}
Some components and utilities will be obviously shared, like authentication or common UI components (like navigation, form elements, etc), date management tools or constants. Other components will have to be evaluated as the apps are built.
This will require some thought before hand, *What components do we have in our separate apps now that need to be shared? What kind of components are they? Are they presentational or transactional? Are any written for a single use case but* can *be made generic?* 
As developers we will have to gauged and decide on a way to pre-emptively decide what should be created as a shared component from the get go. For example if you are creating controls or navigation elements those should probably be shared.
{% enddetails %}

{% details How can a monorepo manage the potential issues arising from poor developer communication and lack of discipline in adhering to pre-agreed rules when using shared or app-specific code? %}
There are a number of methods both manual an automated that can improve on this issue:
1. Create clear documentation outlining best practices and expected standards and conventions.
2. Enforce Code Reviews and PR's by multiple team members to ensure team members adhere to the guidelines. This may sound heavy handed, but will prevent bad practices from spinning out of control.
3. Module Architecture: Organize the codebase in a modular fashion, where shared components and app-specific code are clearly separated.
4. Automated Testing and CI: Setup automated testing to catch issues early and use CI pipelines to run linting checks on PRs.
5. Training and Onboarding: Provide training sessions for new developers to familiarize them with the monorepo, tools and best practices.
6. Regular update meetings: Schedule regular meetings to discuss ongoing work, updates and issues that team members are having with the monorepo. Foster a culture of open communication where developers feel comfortable discussing potential problems and proposing solutions
{% enddetails %}

{% details How does a monorepo prevent issues seen in previous applications, where a lack of documentation and dependency visibility leads developers to create multiple similar routines instead of modifying exiting ones? %}
Monorepo tools in general provide a lot more support to the architecture than legacy apps, including dependency visibility. Informing developers what effects the changes they make will have and where
{% enddetails %}
{% details How does a monorepo handle the need to test a shared dependency across all apps that consume it when updates are made? %}
Any consuming apps would have to under go testing in some form or another to confirm their goals are still being achieved. However much of that testing can be automated by impl unit test or e2e testing with Storybook or Cypress. If you automate the boilerplate testing (eg CRUD), manual testing might only have to be done for edge case scenarios.
{% enddetails %}

{% details How does a monorepo address concerns that updating shared libraries forces all dependent apps to be updated simultaneously, compared to the current approach where libraries can be updated per project, allowing failures to be managed in a smaller, more controlled environment? %}
Some monorepo tools do support a repo-wide set of dependencies that can be overridden on a per-app/lib basis, however this approach should carefully analysed as it can lead to each app having their own list of deps instead of inherit a list of shared deps and then you are back in dependency hell.
{% enddetails %}

{% details How do we know that by using a monorepo, we arent swapping one set of problems for another? There needs to be more research into the pros/cons from teams that have walked thsi road. %}
There are many articles that talk about how a monorepo saved them from the same problems that we are facing. It obviously is not a silver bullet and they described challenges and limitations they had to cater for and overcome.
Just like there are articles that promote the joys of monorepos there are also a few that discourage its usefulness, and nothing sparks a debate in the software community like posting articles that a particular subject is the absolute worst. This lead me to the comment sections which yielded what seems to be the most honest impressions of monorepos:
- A monorepo doesn't have to be the one-repo-to-rule-them-all, it can also mean on repo for related set of services or applications. Monorepos shouldn't be used to encompass an entire company's codebase unless like Google, Facebook (and others) you also have the engineering resources to do so.
- Monorepos can produce complications when scaling, but general consensus is that this is only an issue if you have dozens of developers committing daily to a project with hundreds or thousands of lines of code.
- Monorepos do have challenges, its not disputed, but they can be overcome and the benefits are worth it

**Sources at the end of the post**
{% enddetails %}

{% details What is the breaking point for moving away from our current path? %}
Continuing our current approach will just exacerbate the problem (of code duplication and dependency hell), leading to the product suite as a whole becoming untenable. We shouldn't wait for the breaking point though before acting. We know there is a problem now, we should begin to proactively resolve it while we have the resources do so. Waiting for a breaking point could mean that when we do address it, we are under time constraints that don't allow adequate investigation or experimentation to impl a new tool correctly.
{% enddetails %}

{% details Is there and automated tool that can migrate our apps into a monorepo and identify the common code that needs to be made sharable? %}
There are tools to import a standalone repo into a monorepo structure but to conduct code analysis to determine shared/duplicate code would have to be done using a separate tool. This could save time on the migration but it would add the complexity of having to learn and configure these tools for a one-time use. If we had many more repos it could be viable, but I dont think it would add value when migrating the 5/6 we have.
{% enddetails %}

{% details How does using a monorepo change testing by QC of different apps that depend on the same feature change in different environments? Both apps are built together, so it would seem that they are dependent on each other? %}
Remember that a monorepo does not have to deploy a single build artifact. Each app can result in its own build artifact thats published and deployed independently. So if one of the two artifacts are deployed and testing finds a bug. The other artifact can just carry on.
{% enddetails %}

{% details How does a monorepo address concerns regarding read access to the codebase, particularly in the context of hiring an intern, where specific repo/project access is typically granted? %}
This is not a problem that monorepo tools tackle. This would be a GitHub issue, and it does not support sub-directory read-only access.
So to answer your question, there is no solution, read access is all-or-nothing.
This would raise concerns if we were applying the methodology to multiple parts of the business (ie. web-clients, mobile-clients, microservices, etc), but since we are only targeting the web-clients (which are so similar that access to one means you can guess whats in the others) it shouldn't be a concern.
{% enddetails %}

**Posts about experience with monorepos**
 - [Moving to a Monorepo Part 1 - The Journey](https://medium.com/empathyco/moving-to-a-mono-repo-part-1-the-journey-eb63efd8ef64)
 - [Moving to a Monorepo Part 2 - The Destination](https://medium.com/empathyco/moving-to-a-mono-repo-part-2-the-destination-a47e597ff50d)
 - [Moving to a Mono-repo](https://techblog.shippio.io/moving-to-a-mono-repo-f9e12f3f7c84)
 - [Two years of monorepo hand-on experience](https://medium.com/ing-blog/two-years-of-monorepo-hand-on-experience-47246b89a50a)
 - [Journey of a Frontend Monorepo: Here’s What I Learned](https://betterprogramming.pub/journey-of-a-frontend-monorepo-what-i-learned-d6a0d142803f)
 - [Monorepo is a bad idea](https://alexey-soshin.medium.com/monorepo-is-a-bad-idea-5e587e848a07)
 - [Monorepos: Please don’t!](https://medium.com/@mattklein123/monorepos-please-dont-e9a279be011b)
 - [Thanks for sharing. I had a very similar experience.](https://medium.com/@cxmcc/thanks-for-sharing-i-had-a-very-similar-experience-the-pain-points-are-so-similar-ddf1b37f156c)