// dead-code-scan
Paste a module and get back the code you can delete. The scanner masks comments and string literals, indexes every symbol and call site, then walks reachability to flag unused exports, orphan functions and types, unreachable statements, statically dead branches, and stale imports — each with deletable LOC and a deletion-risk rating.
Paste a module above to find deletable code
Heuristic analysis of Python, JavaScript, and TypeScript — no code leaves your browser// how-it-works
Masking pass
Comments and string literal contents are blanked in place, preserving byte offsets and line numbers. Every later pass reads the masked buffer, so an identifier inside a comment or a docstring never counts as a use.
Symbol graph
Function, method, class, and type declarations are extracted with their exact spans, then every call site is located by word-boundary search outside each declaration's own span. Recursive-only references are separated from real call sites.
Reachability + cascade
Statements after a terminating return, raise, or throw in the same block are marked unreachable; constant conditions mark whole branches dead. Dead symbols are then re-resolved so helpers referenced only by dead code fall in a cascade.
Cleanup impact
Every finding contributes a line range. Ranges are unioned into a deduplicated deletable LOC count, scored for deletion risk, and priced as an estimated review-and-delete budget at roughly 1.5 minutes per line plus 4 minutes per range.
// known-limits
Dynamic references
A name that also appears inside a string literal or comment is escalated to high risk instead of being trusted as dead — config tables, test fixtures, and event registries often reference symbols by name.
Framework entry points
Decorated or annotated handlers are called by a runtime, not by code in the file. They are never silently deleted: they are flagged as unused exports with high risk so you can confirm the registration path first.
External consumers
The scanner sees one module. An exported symbol with no internal callers may still be imported elsewhere, which is why exports are never treated as low-risk deletions.
Heuristics, not a compiler
Brace matching is textual: a regular expression literal containing unbalanced braces, or a macro-generated body, can skew spans. Confirm each range in the queue before removing it.
// verdict
## // verdict
Should I adopt this? Yes for pre-cleanup triage on your own code. No as a delete list.
What it actually is. A client-side analyzer that flags symbols reached only through detected-static paths — functions never referenced, exports nothing imports, branches a conservative reachability pass can't reach. It runs in your browser; no upload, no backend.
Use it when you're about to do a cleanup pass and want a candidate list to investigate, or when you want to check whether an export is genuinely consumed before deprecating it.
Do not treat findings as safe-to-delete. Static analysis has real blind spots on dynamic dispatch, reflection, framework registrations (routes, decorators, string-keyed handlers), test fixtures, and code referenced only from build configuration. Deleting anything it flags without confirming with a real build, typecheck, and test run is how regressions ship. The page's own "deletion-queue" list is a to-review list, not a to-delete list.
Run it in a CI-like loop yourself: flag → build → search for refs → delete → re-run tests. The tool earns its keep by shrinking the search, not by closing it.
Bottom line: genuinely useful first-pass filter with honest limits stated on the page. Adopt it for targeting cleanup work; keep humans and a test suite as the authority on removal.