Find dead code across a repository
A four-step pass over a repository. It maps the repo, lists exported symbols, checks each for real callers, and ends with a deletion list you can act on, the risky cases kept apart from the safe ones.
Tested on Claude Sonnet · 4.5 ·
-
Map the repository first
Do not start from a file. Ask for the shape of the project so later steps have something to anchor to, and so you notice immediately if the model has misread the structure.
Step 1 Here is the file tree of a repository. Give me, in under 200 words: the entry points, the framework in use, and where the boundaries are between modules. Do not summarise what each file does. {{file_tree}} -
List every exported symbol
One pass per module, not the whole repo at once. Long input makes the model start guessing at names it has not seen.
Step 2 For this module, list every exported function, class and constant, one per line, as: name | file | line. No commentary. {{module_source}} -
Check each symbol for callers
Feed the list back with the search results. The model is not searching your codebase, you are - it is deciding what the results mean.
Step 3 Here is an exported symbol and every textual match for its name in the repository. Decide: is it called anywhere in production code, only in tests, or nowhere? Answer with one word - USED, TESTS_ONLY or UNUSED - then one line of evidence. Symbol: {{symbol}} Matches: {{grep_output}} -
Separate safe from risky before you delete
This step is the reason the workflow is worth running. Anything reached by reflection, a route table, a plugin loader or a serialised class name will look unused and is not.
Step 4 Here is a list of symbols marked UNUSED. For each one, say whether it could still be reached at runtime through: a route or URL table, reflection or dynamic dispatch, a plugin or hook registry, serialisation by class name, or a public package API. Output two lists: SAFE TO DELETE and CHECK BY HAND, with the reason for anything in the second list. {{unused_list}}
Expect about twenty minutes on a medium repository, mostly waiting. You get a list to review and nothing to apply blindly. A model sees dynamic dispatch, reflection and framework entry points as dead code, so the last step exists to catch them.
Notes from the author
Step three is where people cut corners, and it is the step that makes the result trustworthy. Skip the grep, let the model guess whether something gets called, and you get a confident list of symbols that are very much in use. On a repository with heavy dependency injection most of the output will land in CHECK BY HAND. That means the workflow is working.
For information only, not professional advice. You use it at your own risk and we are not liable for any loss or damage. See the disclaimer.
Tagged