Files
initiative/specs/007-add-knip/spec.md

5.9 KiB

Feature Specification: Add Knip Unused Code Detection

Feature Branch: 007-add-knip Created: 2026-03-05 Status: Draft Input: User description: "Add Knip to the project to detect unused files, exports, dependencies, devDependencies, and types across the pnpm workspace and enforce it as part of the quality gate."

User Scenarios & Testing (mandatory)

User Story 1 - Detect Unused Code on Commit (Priority: P1)

As a developer, I want unused files, exports, dependencies, devDependencies, and types to be automatically detected when I commit, so that dead code never accumulates in the codebase.

Why this priority: This is the core value proposition — catching unused code as part of the existing quality gate ensures every commit keeps the codebase clean without requiring manual effort.

Independent Test: Can be fully tested by introducing an unused export into any workspace package and running the quality gate; the gate should fail with a clear report identifying the unused export.

Acceptance Scenarios:

  1. Given the quality gate is run, When all files, exports, dependencies, and types are in use, Then the unused-code check passes successfully.
  2. Given a file contains an unused export, When the quality gate is run, Then the check fails and reports the specific unused export and its file location.
  3. Given a workspace package lists a dependency that is never imported, When the quality gate is run, Then the check fails and reports the unused dependency and the package it belongs to.
  4. Given a file exists that is not imported or referenced anywhere, When the quality gate is run, Then the check fails and reports the unused file.
  5. Given a type or interface is exported but never imported elsewhere, When the quality gate is run, Then the check fails and reports the unused type.

User Story 2 - Run Unused-Code Check Independently (Priority: P2)

As a developer, I want to run the unused-code detection as a standalone command, so that I can inspect and fix issues before committing.

Why this priority: Developers need a fast feedback loop to discover and address unused code during development, not just at commit time.

Independent Test: Can be tested by running a dedicated command from the workspace root and verifying it produces output listing any unused items found across all workspace packages.

Acceptance Scenarios:

  1. Given the developer is at the workspace root, When they run the standalone unused-code command, Then it analyzes all workspace packages and reports results.
  2. Given unused items exist across multiple workspace packages, When the standalone command is run, Then all unused items are reported with their package and file location.

Edge Cases

  • What happens when a file is only used as an entry point (e.g., main or exports field in package.json)? It must not be falsely reported as unused.
  • What happens when test files import modules only used in tests? Test-only dependencies and test utilities must not be flagged.
  • What happens when configuration files (e.g., vite.config.ts, vitest.config.ts) reference plugins or packages? These must not be flagged as unused.
  • What happens when workspace packages cross-reference each other via the workspace:* protocol? Internal workspace dependencies must be recognized.
  • What happens when a type is re-exported from a barrel file? The re-export chain must be traced correctly.

Requirements (mandatory)

Functional Requirements

  • FR-001: The system MUST detect unused files across all workspace packages (packages/domain, packages/application, apps/web).
  • FR-002: The system MUST detect unused exports (functions, constants, types, interfaces) across all workspace packages.
  • FR-003: The system MUST detect unused dependencies and devDependencies listed in each workspace package's package.json.
  • FR-004: The system MUST be integrated into the existing quality gate (pnpm check) so that any unused code causes the gate to fail.
  • FR-005: The system MUST provide a standalone command runnable from the workspace root to check for unused code independently of the full quality gate.
  • FR-006: The system MUST correctly recognize entry points defined in each package's package.json (main, exports, types fields) and not flag them as unused.
  • FR-007: The system MUST correctly handle pnpm workspace cross-references (workspace:* protocol) and not flag internal workspace dependencies as unused.
  • FR-008: The system MUST correctly recognize test file patterns and not flag test-only utilities or test dependencies as unused when they are consumed by tests.
  • FR-009: The system MUST correctly recognize configuration files and their plugin/dependency references.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: The quality gate fails when any unused file, export, dependency, or type is present, with zero false negatives for straightforward unused items.
  • SC-002: The quality gate passes on the current codebase without false positives (no legitimate code is flagged as unused).
  • SC-003: A developer can run the standalone unused-code check and receive results covering all workspace packages.
  • SC-004: The unused-code report identifies the specific item (file, export name, dependency name) and its location (package and file path) for each finding.

Assumptions

  • Knip is the chosen tool for unused-code detection as specified by the user.
  • The tool will be added as a root-level development dependency since it analyzes the entire workspace.
  • Knip's built-in support for pnpm workspaces, TypeScript, Vitest, React, and Vite will handle most configuration automatically with minimal manual setup.
  • The existing Lefthook pre-commit hook runs pnpm check, so adding the unused-code check to pnpm check automatically enforces it on every commit.