Skip to content

Architecture analysis rules

A finding records ruleId, category, severity, file, line, evidence, and recommendation. Open the named file and verify the intended design before editing it. NKLattice reports static source signals; it does not prove that an import or export is harmful.

Rule ID Default level Signal and first review step
module-cycle Error Local runtime imports form a strongly connected group. Inspect dependency direction and move a shared contract to a lower layer if needed.
high-fan-in Warning More than 8 runtime local import edges enter a module. Review its stability before changing its public interface.
high-fan-out Warning More than 10 runtime local import edges leave a module. Look for unrelated responsibilities.
deep-dependency-chain Warning A runtime local import chain exceeds 6 hops. Inspect whether intermediate layers carry useful boundaries.
orphan-module Info A non-route module has no resolved local incoming or outgoing edges in a project with multiple modules. Confirm whether it is an entry point.
duplicate-import Warning A module repeats a runtime import specifier. Combine imports if both declarations are needed.
unused-export Info An exported value in an imported non-route module has no resolved local importer. Check package and runtime consumers before removing it.
large-component Warning A file with a recognized JSX component exceeds 200 lines. Extract only a cohesive responsibility.
deep-jsx Warning JSX nesting is deeper than 6. Consider a named child component when it clarifies intent.
high-complexity Warning Approximate branch complexity exceeds 15. Review the branches and split focused logic where useful.

These are ten rule IDs, with fan-in and fan-out counted separately. A configured module boundary contributes another finding under its own policy ID and chosen severity. Architecture policy explains the thresholds and custom boundaries.

The scanner includes JS/TS source files under the analyzed root and resolves static import declarations and re-exports to other scanned files. It uses the root tsconfig.json when available. External packages and unresolved files do not become local graph edges. Declaration-level import type and export type are excluded from runtime cycles, fan-in/out, and boundary checks.

The cycle rule identifies a strongly connected group; the listed module order is not an exact execution path. Fan counts are edge counts, so repeated imports can increase them. A line number of 1 on a file-level metric points to the file, while import-specific rules can point to the import line.

The complexity number starts at 1 and increments for syntax such as if, loops, catch, conditional expressions, case blocks, and && / || expressions. It is an approximation, not a full complexity audit.

  • An orphan-module can be an app entry point, a test entry point, or a file used outside local static imports.
  • unused-export checks only resolved local importers and is skipped for recognized Next app/ and pages/ route files. It cannot see every external consumer, dynamic import, or runtime reflection.
  • The parser does not build the project or follow every require() or import() expression. A missing graph edge may mean a source pattern was not covered.
  • A large-component finding applies to the whole file when it contains a top-level capitalized JSX function or variable. It does not measure one component body in isolation.

When a finding is valid but the chosen limit does not fit the team, adjust the threshold or a boundary rule in a reviewed .nklattice.json. Weight changes affect the score, not whether the finding appears.