Unused Code Cleaner: The Claude Code Agent That Pays Down Technical Debt Automatically
Dead code is a tax. Every unused import, orphaned function, and abandoned class is something the next developer has to read, reason about, and decide whether to trust. Over time, the accumulation becomes a real problem: longer build times, larger bundles, cognitive overhead that slows down onboarding, and refactors that are harder than they should be because nobody can tell what’s actually used.
The frustrating part is that cleaning it up is rarely the bottleneck — finding it is. Manual dead code hunting across a 50,000-line codebase is tedious, error-prone, and easy to deprioritize. Tools like depcheck, ts-unused-exports, and vulture help, but they require you to remember to run them, interpret their output, and then do the actual removal yourself. None of them know your framework conventions. None of them run your tests after each deletion to confirm nothing broke.
The Unused Code Cleaner agent for Claude Code changes the calculus. It combines static analysis, dependency graph traversal, framework-aware preservation rules, and incremental validation into a single workflow that you can trigger proactively — not just when things have gotten out of hand.
When to Use This Agent
This agent is designed to be used proactively, not reactively. The system prompt explicitly calls this out. Here are the scenarios where it delivers the most value:
After a Major Refactor
You just split a monolith into services, or migrated from Redux to Zustand, or rewrote your data layer. The old abstractions are gone, but their supporting code — utility functions, helper classes, type definitions — often lingers. This agent maps what’s actually referenced post-refactor and removes what isn’t.
When Removing a Feature
Feature flags come down, A/B tests end, product requirements change. Deleting the feature’s entry point is easy. Tracking down every utility function, imported library, and shared component that was only used by that feature is not. The agent builds the dependency graph and handles the cascade.
Pre-Production Deployment
Before cutting a release, running this agent is a fast way to reduce bundle size, clean up your import surface, and ensure you’re not shipping code that was meant to be temporary. It’s a legitimate pre-deployment checklist item, not just housekeeping.
Onboarding a Legacy Codebase
You’ve inherited a codebase with years of accumulated drift. Running this agent gives you a map of what’s dead before you start making changes, so you’re not building mental models around code that was already irrelevant.
CI Pipeline Integration
Teams that take code quality seriously can trigger this agent as part of their development workflow — on feature branch completion, as a pre-merge check, or as a scheduled maintenance task. The report format is structured and machine-readable enough to act on programmatically.
What Makes This Agent Powerful
Multi-Language Static Analysis
The agent handles Python, JavaScript, TypeScript, and Java out of the box. It doesn’t just search for string matches — it performs AST-based analysis in Python to track import statements against actual symbol usage, and uses tools like depcheck and ts-unused-exports for JavaScript and TypeScript projects. Each language gets the appropriate analysis strategy.
Dynamic Usage Pattern Detection
This is where most simple dead code tools fail. If your code uses getattr(), eval(), or globals() in Python, or window[], this[], or dynamic import() in JavaScript, the agent knows not to touch the symbols that might be accessed through those mechanisms. Reflection in Java and Spring annotations are similarly preserved. This is what separates a useful tool from a dangerous one.
Framework-Aware Preservation
The agent has explicit rules for Django models and migrations, Flask routes and blueprints, FastAPI endpoints, React components and hooks, Vue directives, Angular decorators, and Spring beans and controllers. It won’t remove a Django model because it isn’t explicitly called in Python — it knows that Django’s ORM references models through string lookups and migrations. It won’t strip a Spring @Service annotation because it understands how dependency injection works.
Incremental Removal with Validation
Rather than deleting everything and hoping tests pass, the agent removes elements one at a time, validates syntax, runs your test suite, and rolls back if anything breaks. This makes the process auditable and safe, even on codebases without complete test coverage.
Automatic Backup Before Any Changes
Before touching a single file, the agent creates a timestamped backup of the entire project. If something goes wrong — or you just change your mind — you have a clean recovery path without needing to dig through git history.
Structured Reporting
Every run produces a report that covers files analyzed, unused elements detected, what was safely removed, what was preserved and why, and impact metrics including lines removed and size reduction. This is useful for pull request descriptions, technical debt tracking, and just understanding what the agent actually did.
Real-World Examples
Scenario: Post-Refactor Python Cleanup
A team finishes migrating their authentication system from a custom JWT implementation to a third-party library. The old implementation had a dozen helper functions spread across three files. Here’s how the agent interaction might go:
Developer: We just replaced our custom JWT logic with python-jose.
Can you clean up what's left over?
Agent: I'll analyze the codebase. Let me start by mapping all references
to the old jwt_utils module and its exports.
Scanning 847 files...
Found the following in jwt_utils.py:
- encode_token() — 0 external references
- decode_token() — 0 external references
- validate_expiry() — 0 external references
- _base64_pad() — 0 external references (private, no dynamic access)
- JWT_SECRET — referenced in settings.py via getattr() — PRESERVING
Creating backup at ./unused_code_backup_20241203_142301...
Removing encode_token() from jwt_utils.py...
Syntax valid. Running pytest... 847 passed. ✓ Removed.
Removing decode_token()...
Syntax valid. Running pytest... 847 passed. ✓ Removed.
[continues for remaining functions]
Summary:
- Files analyzed: 847
- Unused functions detected: 4
- Safely removed: 3 (127 lines)
- Preserved: 1 (JWT_SECRET — dynamic access via getattr)
- Size reduction: 4.2KB
Scenario: JavaScript Feature Flag Cleanup
A product team deprecates an experimental dashboard feature after an A/B test. The feature flag is removed, but the supporting components remain.
Developer: We killed the ExperimentalDashboard feature. Flag's gone,
but there's probably leftover code. Can you find and remove it?
Agent: Running module analysis on the JavaScript codebase...
Entry points identified: src/index.js, src/App.jsx
Building import graph from entry points...
Components with zero import path to entry points:
- src/components/ExperimentalDashboard/index.jsx
- src/components/ExperimentalDashboard/DataGrid.jsx
- src/components/ExperimentalDashboard/FilterPanel.jsx
- src/hooks/useExperimentalFilters.js
- src/utils/dashboardHelpers.js
Checking for dynamic imports and string references in templates...
No dynamic references found for these modules.
Running npx depcheck to confirm package-level impact...
'recharts' is now an unused dependency — was only referenced
by ExperimentalDashboard components.
Safe to remove:
- 5 component/utility files (312 lines)
- 1 npm dependency (recharts)
Proceed with removal and test validation?
How to Install
Installation is straightforward. Claude Code automatically discovers agents defined in your project’s .claude/agents/ directory. To install the Unused Code Cleaner:
1. Create the agents directory if it doesn’t exist:
mkdir -p .claude/agents
2. Create the agent file:
touch .claude/agents/unused-code-cleaner.md
3. Paste the full system prompt into that file. The system prompt starts with the role definition (“You are an expert in static code analysis…”) and includes all the analysis checklists, framework preservation rules, execution process, and safety guidelines.
4. That’s it. Claude Code will load the agent automatically on next startup. You can invoke it by name in any Claude Code session within that project.
The agent file travels with your repository. Commit it to version control and every developer on the team gets access to the same agent configuration without any additional setup steps.
Practical Next Steps
Install the agent today and run it against a branch that’s just had a significant refactor. Don’t start with main — start somewhere lower-stakes so you can review the report and understand what the agent considers “safe to remove” in the context of your specific frameworks and patterns.
Once you trust its judgment on your codebase, add a proactive cleanup pass to your feature branch workflow. The report it generates is a useful artifact for pull requests: it gives reviewers confidence that the branch didn’t leave behind ghost code, and it quantifies the scope of cleanup in terms reviewers can actually evaluate.
For teams running TypeScript, make sure ts-unused-exports is available in your dev dependencies so the agent can leverage it during analysis. For Python projects, confirm that pytest is runnable from the project root. The agent’s incremental validation relies on being able to run your test suite — the tighter your test coverage, the more confidently it can remove code without manual review.
Dead code accumulates by default. This agent makes cleaning it up the path of least resistance.
Agent template sourced from the claude-code-templates open source project (MIT License).
