Technical debt is the accumulated cost of shortcuts, outdated patterns, and deferred cleanup in a codebase. Dead code -- functions, files, and imports that are never executed -- is one of the largest and most overlooked contributors to this debt.
Unlike other forms of technical debt (poor abstractions, missing tests, inconsistent patterns), dead code has a unique property: removing it has zero risk of changing behavior. If code is truly never executed, deleting it cannot break anything. This makes dead code removal one of the highest-ROI refactoring activities a team can undertake.
The Hidden Cost of Dead Code
Dead code does not cause bugs directly. Its cost is indirect, which is why teams often ignore it:
Developer Time Waste
Every time a developer reads through a file, they spend cognitive effort understanding all the code in it -- including dead code. In a file with 30% dead code, nearly a third of that effort is wasted.
When searching for a function name, dead code creates false matches. A developer investigating a bug might spend 20 minutes reading a dead function before realizing it is never called.
Onboarding Friction
New team members do not know which code is alive and which is dead. They read dead code, ask questions about it, and sometimes even write tests for it. In a codebase with thousands of lines of dead code, this can add days to onboarding.
Misleading Metrics
Code coverage tools count dead code as uncovered, making your coverage numbers look worse than they are. Lines-of-code metrics overcount the actual size of your application. Complexity metrics include dead branches that never execute.
Dependency Bloat
Dead code often imports libraries that nothing else uses. These phantom dependencies increase install time, bundle size, and the surface area for security vulnerabilities.
Measuring Dead Code
Before you can reduce dead code, you need to measure it. Here are the key metrics:
Unused export count: The number of exported functions, classes, and variables that are never imported anywhere. Tools like ts-prune report this directly.
Orphaned file count: Files that are not imported by any other file in the project. These are entire modules of dead code.
Unused import count: Import statements that bring in values never referenced in the file. ESLint's no-unused-vars catches these.
Dead code percentage: The ratio of dead lines to total lines. This gives a high-level view of how much of your codebase is unused.
A Systematic Removal Process
Removing dead code at scale requires a systematic approach:
Step 1: Baseline Scan
Run a full-project scan to establish your current dead code count. Record the numbers: unused exports, orphaned files, unused imports.
Step 2: Prioritize by Impact
Not all dead code is equally costly. Prioritize removal by:
- Orphaned files first -- these are entire files that can be deleted with no risk
- Unused exports in high-traffic files -- files that developers read frequently benefit most from cleanup
- Unused imports -- quick wins that reduce bundle size
Step 3: Incremental Removal
Remove dead code in small, focused pull requests. Each PR should:
- Remove one category of dead code (e.g., all orphaned files, or all unused exports in a specific module)
- Include a passing test suite run
- Include a successful build
Step 4: Prevent Regression
After cleaning up, prevent new dead code from accumulating:
- Add ESLint rules that flag unused imports and variables as errors
- Run periodic scans (weekly or per-sprint) to catch new dead code
- Include dead code metrics in your engineering dashboard
The ROI of Dead Code Removal
Teams that systematically remove dead code report measurable improvements:
- Faster onboarding: New developers ramp up faster when they are not reading irrelevant code
- Smaller bundles: Frontend projects see immediate bundle size reductions, often 5-15% for projects that have never been cleaned
- Fewer false positives: Search results, code navigation, and IDE suggestions become more accurate
- Better coverage numbers: Removing dead code from coverage calculations gives a more honest picture of test quality
Getting Started
The easiest way to start is with a single scan. CleanAI runs in VS Code and Cursor, combining ts-prune, ESLint, Periphery, and Vulture into one unified report. Run a scan, review the findings, and start removing dead code today.
The best time to remove dead code was when it became dead. The second best time is now.