Dead Code Detection
Mapnostics reads your repository into a symbol graph and flags exports, symbols and branches that nothing reaches. Every finding carries a confidence score and the evidence behind it, so you can see why the scan believes what it believes.
What is dead code
Dead code exists in your repository but is never reached at runtime. It accumulates over years of feature flags, refactors and abandoned experiments. Left alone it misleads engineers, inflates bundles and hides real risk.
The tab
The scan is a button, not part of indexing — it runs in batches you can stop and resume, and the log follows it file by file. This is the tab after a completed run.
What the scan leaves out
Three kinds of file are never handed to the file scan, so they cannot produce a finding: fixtures (anything under a fixtures/, __fixtures__/, testdata/ or __snapshots__/ directory — sample inputs a test reads, which nothing is meant to call); the tests themselves, in every language convention Mapnostics recognises; and generated UI primitives such as a shadcn components/ui/ folder. Test-shaped dead code that does matter — a permanently skipped suite, or a module kept alive only by its own test — has its own detector and still appears.
Reading the results
The six tiles
The tiles name who did what, because two of the numbers mean very different things. Candidates is every visible finding. Needs review is the ones still untouched. Auto-confirmed is what the symbol-graph scanner proved on its own, and Confirmed by team is what a person clicked Yes on — they are split apart so the tab never claims a review nobody did. False positives counts the findings a reviewer rejected, which is a result rather than an absence.
Finding types
Findings carry the type the analyzer that produced them writes, and the badge on the card names it:
unused_symbol— the symbol-graph scanner found no reference to this export anywhere.dead— the model-driven analyzer judged the code unused.unreachable— a branch or statement no control-flow path can reach.
Two analyzers landing on the same lines is corroboration, not a duplicate. The card shows both badges and says how many analyzers agree, and keeps each one's wording.
Evidence and status
The evidence panel
Every finding lists the signals behind its score, grouped into three tiers, so a compiler-backed fact never reads like an opinion:
- Structural — compiler-backed graph truth, tagged
ASTorGRAPH. - Operational — commit history and file age, tagged
GIT. - Semantic — the model's reading, tagged
LLM. Interpretive, never proof.
Signals that argued against the finding are listed separately from the ones that argued for it, with the penalty they carried.
Statuses
A finding is flagged until someone resolves it. Confirming records confirmed against your name for the whole organization; rejecting records dismissed. The pipeline also writes suppressed when another signal contradicts a finding, and unverifiable when it cannot be checked. Those two are hidden from the list and summarised above it.
Repository-level waste
Three audits sit below the file findings and do not depend on the file scan, so they render whether or not it has run:
- Unused dependencies — packages declared in package.json that nothing imports.
- Unused assets — images, fonts and static files no source file references.
- Orphan tables — tables your migrations create that no query in the repository reads or writes.
What to do next
- Start with the high-confidence filter — those are the findings with structural evidence.
- Run the Impact Simulator on a file before deleting from it, to confirm the blast radius.
- Reject what is wrong. A dismissal is recorded and keeps the finding from coming back as noise.
- Re-run the scan after the cleanup merges — the Health Score moves only on the next run.