independence

The modules units must not depend on one another, in either direction, directly or through other modules.

Example

[contracts.features-independent]
type = "independence"
modules = ["web/src/features/*"]
ignore_imports = ["web/src/features/* -> web/src/features/shared"]
web/src/features/checkout web/src/features/catalog web/src/features/shared page.tsx form.tsx api.ts list.tsx button.tsx web/src/lib/cart.ts not a unit direct indirect imports into it are ignored
A feature may not import another, directly or through a module outside them. Imports into shared are ignored.

Each directory under web/src/features is a unit, and no feature may depend on another: features/checkout importing features/catalog/api.ts breaks the contract, and so does an indirect route such as features/checkout → web/src/lib/cart.ts → features/catalog.

features/shared matches features/* too, so every feature that uses it would be flagged. The ignore_imports entry exempts imports into shared, while shared importing a feature is still flagged.

A chain through a third unit is reported as two violations, one on each side of it.

Options

OptionDefault
modulesrequiredSelectors. The units may not overlap.
allow_indirect_importsfalseOnly direct imports count.

Common options

Like every contract type, independence also takes:

OptionDefault
typerequiredThe contract type, such as "layers".
namethe idThe title shown in the output.
severity"error""warn" reports a broken contract without failing the check, for rolling a contract out gradually.
exclude_kinds[analysis] exclude_kindsThe import kinds to leave out, e.g. ["type"].
reexports[analysis] reexports"transparent" sees an import of names from a [pass-through module](../concepts.md#pass-through modules) as imports of the modules that define them, as bundlers load them; "opaque" as an import of the pass-through module. Not for encapsulation.
ignore_imports[]"<selector> -> <selector>" entries: the direct imports between them are left out of the contract.
unmatched_ignore_imports"error"Whether an ignore_imports entry that matches no import breaks the contract ("error"), is a warning ("warn") or is fine ("none").
guidancenoneText shown under each violation, such as how to fix it.