Worked example — anatomy of a dependency-cruiser rule.
dependency-cruiser (or eslint-plugin-import / ArchUnit in Java) reads your .dependency-cruiser.js config and fails the build when an import crosses a forbidden edge. Every rule has the same four fields:
| Field | Purpose |
|---|
name | Human-readable id printed in CI when the rule trips. |
severity | 'error' fails the build; 'warn' is informational. |
from | Path pattern (regex) — which files this rule applies to. |
to | Path pattern (regex) — which imports are forbidden from those files. |
A complete, runnable config:
module.exports = {
forbidden: [
{
name: 'domain-must-not-import-infrastructure',
severity: 'error',
from: { path: '^src/domain' },
to: { path: '^src/infrastructure' }
}
]
};
The rule above is the executable form of the hexagonal contract from Level 4: if any file under src/domain/ ever imports a module under src/infrastructure/, the build dies. That's a fitness function — architecture protected by CI, not by code review.