Mono-repository folder structures

Every developer has their own way of structuring their code base. There is no right or wrong way, but some strategies have at least had some logical thought 😉

This is a sample of how I generally structure my mono-repos when they need to scale to many organisational platforms, apps, and projects.

Why Mono-repository?

  • Simplified code management: With a mono-repository, all code for a project or organization is stored in a single repository. This allows for easier code management, versioning, and collaboration among developers.
  • Improved code reuse: By having all code in one place, it becomes easier to identify and reuse common components, libraries, and utilities across different projects within the organization, leading to increased efficiency and consistency.
  • Streamlined dependency management: With a mono-repository, managing dependencies becomes simpler. Different projects can share the same set of dependencies, reducing conflicts and making it easier to update and maintain dependencies.
  • Enhanced code visibility and knowledge sharing: Having all code in one repository promotes better visibility among team members. Developers can easily discover and understand code in other projects, fostering knowledge sharing and cross-pollination of ideas.

These are just a few of the benefits that a mono-repository can offer, and they can vary depending on the specific needs and context of the organization.

Google stores billions of lines of code in a single repository and it is used by 95% of its developers.

If you think it’ll never work for your organisation as you have too much stuff, then think again. Google’s repository statistics are as follows:

  • Total number of files: >1 billion
  • Number of source files: >10 million
  • Lines of source code: 2.5 billion
  • Depth of history: >35 million commits
  • Size of content: >100TB
  • Commits per workday >40,000

You can find a research paper on it at

Top Level Folders

This is a generic structure. In Azure DevOps and GitHub there are specific folders that may also be useful and/or required (e.g. /.github or /.azure-pipelines).

docsDocumentation files. These can be pdf versions tools and consumed API’s, architecture guides etc..
This is not the documentation for this repository. That I keep that in a dedicated Wiki repo. This is the case out-the-box in GitHub and Azure DevOps wikis.
infrastructureInfrastructure as Code (IoC) – ARM, Bicep, Pulumi, Scripts and Terraform files, including shared. More details on this below.
pipelinesYAML release pipeline definitions and all pipeline variables

For detail on my strategy for managing YAML pipelines and pipeline variables see <coming soon>
resourcesImages, branding guides and other assets not required in source
srcSource files. Where sensible, use namespaces as folder names. More details on this below.
testingAutomated, integration and other test assets such as Postman collections and Selenium scripts.
utilitiesTools and utilities. These may be things like command line tools, scripts or utilities that can help your development team. Best not to store large binaries here, but maybe files that point to more suitable storage locations.
readme.mdEach folder should at least have one file explaining what that folder’s purpose is and how it should be used. Make things obvious.

src Folder

For the /src (code source) folder, I like to have a top-level templates area with sample projects and files, as well as an organisation/repo wide common code area. This example structure has two major applications, that I call ‘Platforms’, as they can have several microservices and front-end apps. Here, as an example, each ‘Platform’ has two microservices (REST API plus data back-end). Each microservice has its own infrastructure as code (IaC) element too.

Code re-use should be encouraged as much as possible. To facilitate the widest possible re-use, I add a ‘common’ folder at the top level and at every other level in the org-platform-app hierarchy. The higher up the hierarchy a component can sit the better and designing to this principal should be encouraged.

srcSource files. Where sensible use namespace
src/_templateA place for storing boilerplates and templates for new projects to have a fast and consistent start.
src/commonCommon libraries that can be used across organisation domains and apps
src/common/org.common.contractsCommon data transfer object contracts/interfaces. This allows api and message contracts to be consistent across projects
src/common/org.common.extensionsCommon extension methods that are of widespread use
src/common/org.common.utilitiesCommon utility functions and code
src/{solution or domain or project}A subfolder to hold the domain specific projects and services. E.g. ‘src/eCommerceApp/’
src/{solution or domain or project}/commonCommon libraries that are specific to this ‘Platform‘ only and have no utility across the organisation.

infrastructure Folders

Key Strategy

Whether you are using Terraform, Pulumi, Bicep, ARM, PowerShell or CLI, the key strategy for IaC is to split the infrastructure stack deployment into 3 main layers. This is to minimise the impact of changes when add or changing things at the app level, which is where most of the changes will be happening.

  1. Common Infrastructure
  2. Application Base Platform Infrastructure
  3. Application Component Infrastructure

Common Infrastructure

This base layer changes very infrequently and comprising the core underlying infrastructure. Subscriptions, Core AD security elements, Networks and VNet Peers.

Also included are any large and expensive resources that need to be shared across projects, applications, initiatives, and platforms. These will include APIM and Front Door, CDN’s and AD tenants etc…

Application Base Platform Infrastructure

This layer covers all the common resources that may be needed for one or more of the projects/applications components. This would include such items as the SQL Server, but not the databases. Or the Cosmos DB, but not the containers.

Application Component Infrastructure

This is the top layer and comprises the elements that are directly controlled and required by the developers are specific to a single project or functional element, such as a Microservice.

This would be adding any specific databases or container to SQL Servers or Cosmos Db instances. Additional storage accounts, or blob containers in an existing storage account. As well as queues or topics into the Base Platforms Service Bus.

infrastructure/Base or core infrastructure code goes here. This will be everything that underpins the organisation. Sometime this can be called the ‘landing zone’.
Items here can be the shared resources that are used by all and any application. e.g. Networks, CDNs, API Managers, Firewalls, Storage and logging infrastructure, Sentinel, Policies etc…
infrastructure/commonThis would be a place to keep shared templates, modules, libraries, helpers etc…
These can then be copied or referenced directly in platform and application specific IoC code bases.
infrastructure/coreThe code base for deploying the Base or Core infrastructure
infrastructure/scriptsBecause we always need scripts!
src/{solution or domain or project}/infrastructureThere will be several layers of IoC. This layer should be dedicated to deploying only the common infrastructure for this platform.
In Azure this might be the
src/{solution or domain or project}/{app or microservice or database}/infrastructureThis layer should be dedicated to deploying only the infrastructure for this microservice, data sources or project. In this way this service can be independently deployed with minimum dependencies.

pipelines Folders

When managing pipelines for large and complex repositories with multiple ‘Platforms’, each containing multiple apps and services, then structure and strategy can be complicated.

To avoid this document getting too long, I have outlined my approach here <link coming soon>

One thought on “Mono-repository folder structures

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.