A module is truly modular when its dependency graph shows clear, one-way relationships and minimal backflow into other parts of the system. If the map shows hubs, cycles, or repeated cross-module references, the module is carrying coupled behaviour rather than clean separation. Use the graph, not the folder tree, as the test.
How to tell whether the boundaries are real
Modularity is not a folder convention or a naming style, it is a relationship property. Teams should ask whether the module can be understood, tested, and changed with limited knowledge of the rest of the system, because a true module carries a narrow contract and hides its internal work. If people must constantly inspect neighbouring code to predict behaviour, the boundary is cosmetic.
A clean module usually has a small surface area, explicit inputs and outputs, and a stable dependency direction. The practical test is whether the module can be removed from the graph without causing a ripple of edits elsewhere. When dependency direction is obvious, the module is doing its own work; when direction is unclear, the system is sharing responsibility in disguise.
Teams often confuse physical clustering with real separation. A module can sit in its own directory and still be deeply entangled through imports, shared state, callbacks, or repeated references to peer internals. The question is not where the code lives, but whether the graph shows a coherent boundary that other parts of the system can rely on.
What the dependency graph reveals that the tree view hides
The graph is the more honest artifact because it shows interaction, not intention. A folder tree can suggest clean ownership while the actual call paths reveal hub-like modules that many others depend on, or cycles that force mutual awareness. Those patterns indicate that the module is coordinating behaviour rather than encapsulating it.
When you see many inbound references, the module may be a shared utility, but it may also be a gravity well that everything else must know about. When you see many outbound references, the module may be acting as an orchestration layer instead of a true unit of abstraction. When you see both, the module is likely acting as a coupling point rather than a modular boundary.
Repeated cross-module references are another warning sign. If the same concepts, data shapes, or helper methods appear in several places, teams are probably duplicating knowledge because no single module fully owns it. That usually means the boundary is not strong enough to contain the behaviour.
When coupling is a design smell, not a structural accident
Not every dependency is a problem, but the pattern matters. A true module may depend on stable, narrow interfaces, while a weak module depends on internals, peers, or implementation details that should have stayed private. Cycles are especially telling because they show that two or more parts of the system cannot evolve independently.
Backflow is the clearest sign that modularity has failed. If changing a module regularly forces edits in unrelated areas, the module does not own a self-contained responsibility. The design may still work, but it is paying for that function with coordination cost, fragility, and slower change.
For teams, the useful distinction is between necessary collaboration and accidental entanglement. Shared domain concepts can justify some links, but if the graph keeps growing sideways instead of deepening through stable interfaces, the module boundary is doing too little work.
Practitioner Guidance
What to verify: Inspect the actual dependency graph for inbound fan-in, outbound fan-out, and cycles, then compare those paths with the module’s intended responsibility. If the graph says the module is central but the design says it is isolated, the implementation has drifted from the architecture.
Decision rule: If a change to one module routinely requires coordinated edits to several others, treat the boundary as leaky even if the code is neatly arranged on disk. Refactor toward a smaller public surface, clearer directionality, and fewer shared internals before arguing about folder structure.
What good looks like: A genuinely modular component has a narrow interface, few reasons for others to reach into it, and a dependency pattern that makes impact easy to predict. The best signal is that the module can evolve without turning nearby code into an extension of its own implementation.
Practitioner takeaway: Modularity is proven by change isolation, not by visual organization. If the dependency graph shows hubs, cycles, or repeated back-and-forth references, the module is part of a coupled system, even when the directory tree looks tidy.
Related resources from NHI Mgmt Group
Deepen Your Knowledge
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.
Bonus 33% off our NHI Course when you subscribe.
Reviewed and updated by the NHIMG editorial team on October 12, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org