No dead code — unused exports, components, and functions
Why it matters
Dead code — unused components, unexported utility modules, unreachable API routes — imposes a cognitive tax on every developer who reads the codebase. Is this file used? Was it intentionally removed? Should I modify it or ignore it? ISO 25010 maintainability.analysability degrades as dead code accumulates. It also creates false positives in security reviews: an unused API route with no authentication looks like a security gap even if nothing calls it. AI-generated codebases accumulate dead code across sessions as earlier implementations get replaced without cleanup.
Severity rationale
Medium because substantial dead code increases cognitive overhead and misleads security reviews, but does not break runtime behavior until a dead module is incorrectly believed to be unreachable and then unexpectedly invoked.
Remediation
Find unused exports and modules automatically:
npx ts-prune # finds unused TypeScript exports
# or
npx knip # comprehensive dead code detection
Before deleting, confirm with git log that code wasn't recently added and is genuinely unreachable. Prevent accumulation with:
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used" }]
Delete confirmed dead code and commit with a descriptive message — git history preserves it if recovery is ever needed.
Detection
-
ID:
no-dead-code -
Severity:
medium -
What to look for: Look for code that is defined but never called or imported. Common patterns:
- Exported functions or components in
lib/orutils/that are never imported anywhere - React components defined but never used in any route or parent component
- API routes that are never called from the frontend
- TypeScript types or interfaces that are defined but never referenced
- Entire files that aren't imported anywhere and aren't entry points
Focus on non-trivial code (>10 lines). Single unused utility functions are acceptable; entire unused modules are not. Check if
eslint-plugin-unused-importsor theno-unused-varsrule is configured to catch this. - Exported functions or components in
-
Pass criteria: Count all exported functions, components, and modules in
src/. No entire unused modules or components found. No more than 2 minor unused exports are acceptable if an ESLint rule would catch them. Report the count: "X of Y exports are actively used." -
Fail criteria: Two or more substantial code units (components, utility modules, or API routes with over 10 lines) are defined but never imported or called anywhere.
-
Skip (N/A) when: The project has fewer than 10 source files — not enough for meaningful dead code analysis. Signal: fewer than 10 distinct source files.
-
Detail on fail:
"Dead code found: components/OldDashboard.tsx (80 lines, never imported), lib/legacy-auth.ts (120 lines, all exports unused), app/api/v1/deprecated-endpoint/route.ts (never called from frontend or tests)."or"15 exported functions in lib/utils.ts have no importers across the codebase." -
Remediation: Dead code imposes a mental tax — developers must read and understand code that does nothing. It also creates false positives in security reviews and makes refactoring riskier (is this code truly unused, or did I miss an import?).
To find unused exports automatically:
npx ts-prune # finds unused TypeScript exports # or npx knip # comprehensive dead code detectionRemove confirmed dead code and add an ESLint rule to prevent accumulation:
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used" }]Before removing, confirm with git history that the code wasn't recently added and is actually unreachable (not just indirectly referenced through dynamic imports).
External references
- iso-25010:2011 · maintainability.analysability — Analysability
- iso-25010:2011 · maintainability.modularity — Modularity
Taxons
History
- 2026-04-18·v1.0.0·Initial import from code-maintainability·automated