You need 2 things for a successful monorepo
You should use monorepos. They help a project scale faster and keeps it sane as it grows. For it to really work, you must have 2 things: structure and rules.

Here are an opinionated structure and set of rules I’ve used successfully on about a dozen projects, the largest of which scaled to about 50 engineers. (Large enterprises need rules and structure too, but at that scale, it’s better to use dedicated tooling to manage the overhead of dealing with all of those engineers.)

Structure

You need 3 top-level directories: projects , lib , and tools .

├── projects/

│ ├── athena/

│ └── perseus/

├── lib/

│ ├── custom-orm/

│ └── error-definitions/

└── tools/

├── ci-scripts/

└── terraform/

projects

projects contains all of the deployable (loosely-defined) projects.

lib

lib contains shared code, or code that has the reasonable potential to be shared across different projects.

tools

tools contains all of the tooling around the application that’s not specifically part of the codebase. This is the perfect spot for a Terraform configuration or CI/CD scripts.

Rules

1. Everything MUST have a README

Every README SHOULD include, at a minimum:

A brief description of the project/lib/tool explaining what it is and does. For example, “Athena is a service for managing feature flags for arbitrary subjects.”

Any notable quirks (this should be close to the top of the README). For example, “This project depends on _________ library which is only available on Ubuntu 18.04 and later.”

A walkthrough of how to use the module from scratch. There SHOULD NOT be any initiated knowledge required beyond some common fundamentals (e.g. Docker, bash commands, etc.). For example, “To install custom-orm run pipenv install git@github.com/org/monorepo#egg=lib/custom-orm in the target project.”

Here’s a minimum example README for Conductor, an imaginary project.

2. Projects MUST NOT depend on other projects

If you want to share code between projects, use a lib . Everything in projects MUST stand independent of each other.

3. The repo MUST use trunk-based development

This one is mandatory for most competent systems, though you could argue for an alternative branching method if that works for you. I’ve found that trunk-based is easiest when working across multiple teams, especially on young projects.
['Jacob Bennett']
['Monorepo', 'API', 'Software Development']