Modularity


Some systems are just too big for anyone to fully understand. So how do we still build and work on them? The time-tested strategy is divide and conquer: split the system into smaller pieces we can handle, then put them back together to solve the bigger problem. But splitting alone isn’t enough. The value lies in how we split it, and how we connect the parts.

Good modular design is about enabling local reasoning. You should be able to fully understand a module without having to figure out the whole system. You should be able to change a module without forcing changes everywhere else. That’s only possible with clear, stable boundaries between modules. In other words, well-defined interfaces. Interfaces aren’t just the glue that connects modules; they are the abstraction that lets us make a few key assumptions and safely ignore the rest.

We can think of an interface as a contract between suppliers and consumers. It defines what suppliers require and what they promise in return. A well-designed interface can also enable reuse: if it supports multiple use cases, we can rely on existing modules instead of building new ones from scratch. But this flexibility must not come at the cost of local reasoning. An interface that tries to serve too many purposes often ends up serving none well.

It’s important that we take extra care to specify the contract of each interface, and to make sure that all modules in the system respect these contracts. That’s what enables strong and scalable systems. Contracts give us the freedom to make certain kinds of changes locally, without causing ripples through the entire system. We can replace how a module works inside, while maintaining its contract. We can loosen its requirements, so it fits more use cases. We can tighten its guarantees, so others can rely on it more strongly.

This approach scales well because modularity is fractal. At the top level of a system, we have modules connected by interfaces. But if we zoom into any one module, we can apply the same principles again: divide and conquer, define clear boundaries, reason locally. The same thinking that helps us manage a whole system can help us manage each of its parts.