Monorepo Versus Bill of Materials: Shaping Your Project
November 18th, 2021
During most of my software development career, the usual code organisation pattern was a monolithic, single repository or Monorepo. Within that single code repository, every piece of source code, every sub-module, and every package manager file lived side by side, so development teams would push their commits to one place, sometimes breaking the build and creating cross repo ripple effects. In this single repository world, dependency management and version control often became an after-thought, and supply chain security weaknesses could creep in unnoticed. Every once in a while, this goliath was released as a set of artifacts. Before this may happen, all development activity ceases as we need to stabilise the code base, update any security vulnerabilities, and make sure every component is ready to be released. In effect, a single commit could lock the whole organisation, blocking continuous integration pipelines and slowing the overall development workflow.
At Chronicle Software, our development efforts are structured around the Maven Bill of Materials (BOM) paradigm, which can be viewed as a polyrepo architecture dependency strategy, and an alternative to a traditional monorepo. From a supply chain perspective, the BOM is a form of “materials SBOM” – a software bill of materials that explicitly lists every source library and version, simplifying downstream software composition analysis and static application security testing. At first, I met this technology with scepticism. Thirty-five git repositories instead of just one? Multiple repos, or a multi repo setup, seemed like administrative overhead. Having to update dependency versions in a separate BOM repository just to test cross-module changes felt like busywork. There was suspicion that it would only create busywork. A bit later, I have changed my mind significantly, as the polyrepo approach began to demonstrate measurable benefits for supply chain security, dependency updates, and architecture dependency management.
Ease of Use
First of all, it provides immediate value for our users: they don’t need to track specific versions of Chronicle products manually, wrestle with semantic versioning conflicts, or worry about mismatched source libraries. Instead, they pick a version of the BOM dependency and import a few, or as many artifacts as they wish without specifying their versions, and always get compatible ones. From the viewpoint of application security testing teams, this single BOM reference becomes the authoritative software materials SBOM, enabling automated scanning for security vulnerabilities and supply chain attacks.

By relying on a BOM, users also gain a cleaner repository structure. They no longer need to explore impact monorepo versus multiple teams in one repository; their own projects can stay small, focused, and secure, consuming Chronicle components with minimal friction.
Release Early, Release Often
Using a Bill of Materials also provides significant value for us: We can ship new releases faster than having a Monorepo would ever allow, since only affected products need to be built, tested, and released. This aligns with modern continuous integration and continuous deployment practices, where multiple teams operate on separate repositories yet depend on a single, immutable software materials SBOM for compatibility. For most new releases, the majority of our codebase is not touched, with versions retained from the previous Bill of Materials release. Of course, we still run any production changes against the whole array of tests contained in all projects before merging to the main branch – a process that includes automated application security testing and software composition analysis – which happens in the background so it does not hinder productivity. Before performing the release, we just need to bump all affected artifacts’ versions in the Bill of Materials POM file, guaranteeing consistent dependency management across the polyrepo architecture:

This small edit is effectively a single commit across the BOM, yet it orchestrates version updates across dozens of separate repositories. From a software supply chain viewpoint, this practice narrows the blast radius of changes, reduces the chance of supply chain attacks, and keeps the line of provenance crystal clear for auditors.
Change, One Commit a Time
BOM allows us to gradually improve a core library without the risk of breaking all downstream dependencies at once. In the case of a monorepo, API or behaviour changes usually need to be done in a single large “code bomb” commit when a change affects a lot of code in depending projects, complicating code review and slowing down any review tool or code review tool process. The changes may be pushed under a SNAPSHOT version of the core library as they evolve, while the BOM will still refer to a previous, stable version of that library. We are free to decide when to release the library version, while still having the development process in the main branch, as opposed to keeping it in a feature branch that is bound to diverge from the main branch and needs repetitive manual merges. This model improves dependency updates cadence and reinforces supply chain security by ensuring every released component has passed static application security analysis, unit tests, and integration tests in isolation.
Benefits of Structured Dependencies
The legacy modular approach is to spin off common code, such as network layer, serialization, logging – by creating separate libraries with their own release life cycle. Still, developers often ended up copying the code from these libraries to improve it without waiting for the next release, then pushing it upstream later. Moreover, their users could end up with different, conflicting versions of a library, leading to “dependency hell” and hidden security vulnerabilities.
A Monorepo was in many ways introduced to avoid code duplication between teams who often work on multiple related projects – now they could directly share code residing in a single repository, so the developers would always use the latest version. Not so simple for the users, since the code could only be released when the whole development repository had been stabilised, prolonging feedback loops and increasing risk in the software supply chain.
With a Bill of Materials we can further improve on that. There are separate libraries for low-level abstractions such as data access “Bytes” or marshalling “Wire”. We can immediately release a new version of a library together with a higher-level product, such as distributed “Queue Enterprise”, all in one incremented version of “Chronicle BOM”. All the rest of our projects are unaffected, but still available to the user moving to that “Chronicle BOM” version in their latest stable form. From the perspective of polyrepo architecture, each library lives in its own source control, enabling fine-grained access, clearer audit trails, and easier integration with automated pipeline stages such as security scanning.
Conclusion
Chronicle Software’s ecosystem has a growing number of solutions with a focus on low-latency trading, so we had to make sure our development efforts have a short response loop as well. Using the Bill of Materials-based release system allows us to rapidly deliver new features by shipping them just in time, all while preserving supply chain security, streamlining dependency management, and supporting best practices for software development and application security. In the ongoing discussion of monorepo versus bill of materials – or monorepo vs bill of materials in short – our experience shows that a well-curated materials SBOM and a disciplined polyrepo strategy can outperform a single repository in speed, safety, and scalability.