Skip to content

Knip

knip

Knip-backed rules — dependencies hygiene and dead code.

Knip (depcheck + ts-prune are archived as of 2025, both recommend knip) reports unused/unlisted dependencies AND unused files/exports in one tool. We run it with --no-exit-code so the process never fails on findings — the JSON is the source of truth, and a genuine tool crash surfaces as a non-zero exit that the base treats as an env-failure (knip exit 2 = exception, not findings).

Knip's JSON --reporter json shape (v5): {"files": [...], "issues": [{"file": "...", "dependencies": [...], "unlisted": [...], "exports": [...], "types": [...], ...}, ...]} files is the list of unused files; each issues entry groups the other issue kinds per source file.

NodeDeadCodeRule

Bases: _KnipRule

Score unused files + unused exports (knip).

Mirrors the Python DeadCodeRule (category lint): 100 - items*10.

Source code in packages/axm-audit/src/axm_audit/core/rules/node/knip.py
Python
@register_rule("lint", framework=Framework.NODE)
class NodeDeadCodeRule(_KnipRule):
    """Score unused files + unused exports (knip).

    Mirrors the Python ``DeadCodeRule`` (category ``lint``): ``100 - items*10``.
    """

    @property
    def rule_id(self) -> str:
        """Unique identifier (shared with the Python dead-code rule)."""
        return "QUALITY_DEAD_CODE"

    def score_output(self, parsed: object, project_path: Path) -> CheckResult:
        """Score by the count of unused files + unused exports/types."""
        count = _count_unused_files(parsed) + _sum_issue_kinds(parsed, _DEAD_KINDS)
        score = max(0, 100 - count * 10)
        passed = score >= PASS_THRESHOLD
        return CheckResult(
            rule_id=self.rule_id,
            passed=passed,
            message=f"Dead code: {score}/100 ({count} unused)",
            severity=Severity.WARNING if not passed else Severity.INFO,
            score=score,
            details={"unused_count": count},
            fix_hint="Remove unused files / exports" if count else None,
        )
rule_id property

Unique identifier (shared with the Python dead-code rule).

score_output(parsed, project_path)

Score by the count of unused files + unused exports/types.

Source code in packages/axm-audit/src/axm_audit/core/rules/node/knip.py
Python
def score_output(self, parsed: object, project_path: Path) -> CheckResult:
    """Score by the count of unused files + unused exports/types."""
    count = _count_unused_files(parsed) + _sum_issue_kinds(parsed, _DEAD_KINDS)
    score = max(0, 100 - count * 10)
    passed = score >= PASS_THRESHOLD
    return CheckResult(
        rule_id=self.rule_id,
        passed=passed,
        message=f"Dead code: {score}/100 ({count} unused)",
        severity=Severity.WARNING if not passed else Severity.INFO,
        score=score,
        details={"unused_count": count},
        fix_hint="Remove unused files / exports" if count else None,
    )

NodeDependencyRule

Bases: _KnipRule

Score unused + unlisted dependency hygiene (knip).

Mirrors the Python DependencyHygieneRule: 100 - issues * 10.

Source code in packages/axm-audit/src/axm_audit/core/rules/node/knip.py
Python
@register_rule("deps", framework=Framework.NODE)
class NodeDependencyRule(_KnipRule):
    """Score unused + unlisted dependency hygiene (knip).

    Mirrors the Python ``DependencyHygieneRule``: ``100 - issues * 10``.
    """

    @property
    def rule_id(self) -> str:
        """Unique identifier for this rule."""
        return "DEPS_HYGIENE"

    def score_output(self, parsed: object, project_path: Path) -> CheckResult:
        """Score by the count of unused/unlisted dependency issues."""
        count = _sum_issue_kinds(parsed, _DEP_KINDS)
        score = max(0, 100 - count * 10)
        passed = score >= PASS_THRESHOLD
        return CheckResult(
            rule_id=self.rule_id,
            passed=passed,
            message=f"Dependency hygiene: {score}/100 ({count} issues)",
            severity=Severity.WARNING if not passed else Severity.INFO,
            score=score,
            details={"issue_count": count},
            fix_hint="Remove unused / declare unlisted deps" if count else None,
        )
rule_id property

Unique identifier for this rule.

score_output(parsed, project_path)

Score by the count of unused/unlisted dependency issues.

Source code in packages/axm-audit/src/axm_audit/core/rules/node/knip.py
Python
def score_output(self, parsed: object, project_path: Path) -> CheckResult:
    """Score by the count of unused/unlisted dependency issues."""
    count = _sum_issue_kinds(parsed, _DEP_KINDS)
    score = max(0, 100 - count * 10)
    passed = score >= PASS_THRESHOLD
    return CheckResult(
        rule_id=self.rule_id,
        passed=passed,
        message=f"Dependency hygiene: {score}/100 ({count} issues)",
        severity=Severity.WARNING if not passed else Severity.INFO,
        score=score,
        details={"issue_count": count},
        fix_hint="Remove unused / declare unlisted deps" if count else None,
    )