CodeSolvr
Find dead code, duplicate blocks, and unused dependencies in JavaScript and TypeScript projects — without the false positives.
CodeSolvr runs knip, depcheck, jscpd, ESLint, and npm audit against your workspace, then cross-checks every finding before showing it to you. The goal is a short list you can act on, not a long list you have to triage.
Features
- Unused code — dead files, exports, types, enum members, and class members.
- Over-exported symbols — used inside their own file but never imported elsewhere, so the
export can be dropped.
- Unused dependencies — only packages that two independent tools agree are unused.
- Duplicate code — copy-pasted blocks, with every occurrence linked.
- Health — a 0–100 score, high-complexity functions, and vulnerability counts.
Every finding is clickable and jumps straight to the code.
Two kinds of finding, two different fixes
CodeSolvr separates these, because confusing them is how people delete working code:
| Finding |
What it means |
Safe fix |
| Unused |
Nothing references the symbol anywhere. |
Delete the declaration. |
export only |
The symbol is used inside its own file, but never imported elsewhere. |
Remove the export keyword. Do not delete it. |
Accuracy
A wrong "this is unused" is worse than a missed finding, because you might act on it and delete working code.
- Entry points are detected before scanning. knip decides what is reachable by walking the import graph from your entry points; when it cannot find them, it reports your entire source tree as unused. CodeSolvr reads
main, module, bin, and conventional source paths, maps build output such as out/extension.js back to src/extension.ts, and generates a knip config from the result. A project with its own knip config is never overridden.
- Compiled and generated output (
dist/, build/, out/, .next/, and similar) is never scanned, at any nesting depth.
- References are resolved with comments and string literals masked out, so a name mentioned in prose is not mistaken for a use.
- Findings are cross-checked against the TypeScript language service, which catches symbols reached through barrel re-exports or path aliases. This pass can only remove findings, and only on a positive confirmation — if the language service is unavailable, results are left as the scanner found them rather than silently emptied.
- A dependency is only flagged when both knip and depcheck agree, and it is not a known implicitly-used package (type packages, bundler runtimes, framework plugins, CLI tools).
Usage
Open the CodeSolvr icon in the Activity Bar and run CodeSolvr: Scan Project from the Command Palette, or click the refresh icon in any CodeSolvr view.
Results appear in three views — Unused Code, Duplicates, and Health — and a full JSON report is written to .codesolvr/logs/ (added to .gitignore automatically).
Commands
| Command |
Description |
CodeSolvr: Scan Project |
Run a full scan of the workspace |
CodeSolvr: Refresh |
Re-run the scan |
CodeSolvr: Debug Scan (Raw Output) |
Print raw scanner output and filtered findings to an Output channel |
Settings
| Setting |
Default |
Description |
codesolvr.exclude |
[] |
Extra folder names to exclude, matched at any depth |
codesolvr.duplicates.minLines |
6 |
Minimum identical lines before a block counts as duplicated |
codesolvr.complexity.threshold |
10 |
Cyclomatic complexity at which a function is flagged |
codesolvr.scanOnStartup |
false |
Scan automatically when a workspace opens |
Requirements
Works best on projects with a package.json. ESLint findings require an ESLint config in the project; vulnerability findings require a lockfile. When either is missing, CodeSolvr skips that check and reports it in the Health view instead of failing.
Known limitations
- Symbols reached purely dynamically (
obj["someName"], runtime registries) can be reported as unused, since no static analysis can see those references.
- Reference analysis is text-based with comments and strings masked; a symbol whose name shadows a common local variable may be judged used when it is not.
- Projects whose entry points cannot be detected fall back to knip's defaults. If a scan reports an implausible number of unused files, add a
knip.json declaring your real entry — CodeSolvr will use it as-is.
- Large repositories may take a minute on the first scan.
| |