
Explicit Contract Projects
Giving each module a separate contracts project to prevent circular dependencies
Resources for learning about modular monoliths
A modular monolith is an architectural approach that combines the simplicity of monolithic deployment with the organizational benefits of modular design. It allows teams to build well-structured applications that are easier to maintain and refactor.
Unlike traditional (often messy) monoliths, a modular monolith enforces boundaries between modules, making it possible to evolve the system over time—potentially even extracting services when needed.
A module is an encapsulation boundary that maps to a bounded context. Modules encapsulate their internal behavior and implementation details, including their data model. While many monolithic applications make use of a layered architecture or n-tier architecture, these layers are horizontal and do not enforce encapsulation across logical contexts. The result that even when followed “correctly”, many monolithic apps that rely solely on layered architecture patterns end up devolving into a big ball of mud.
Begin with a well-structured monolith. Define your modules based on business capabilities and enforce boundaries from day one.
As your team and application grow, you can extract modules into separate services. The modular structure makes this transition smoother.
Explore patterns, best practices, and real-world examples to help you build better modular systems.

Giving each module a separate contracts project to prevent circular dependencies

Communicating between modules using events

How to define and enforce boundaries between modules