From quality
Analyze a codebase for dead code, duplicates, and circular dependencies using knip, jscpd, and madge, then validate findings to filter false positives. Use when user says "quality-dead-code-analyzer", "analyze code", "find dead code", "code cleanup", "find duplicates", "unused exports", or "static analysis".
How this skill is triggered — by the user, by Claude, or both
Slash command
/quality:dead-code-analyzerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Runs three static analysis tools sequentially, then validates findings to filter out false positives.
Runs three static analysis tools sequentially, then validates findings to filter out false positives.
Tools used:
The tools are fetched on demand with a package runner — nothing is installed into the project or the skill.
DO NOT use Task agents for this skill. Run all tools directly in the main context using Bash. This prevents infinite retry loops and token waste.
The tools run via npx (npm). If npx is unavailable, fall back to bunx (Bun) — the arguments are identical. Set a RUN variable once and reuse it:
RUN="npx --yes"; command -v npx >/dev/null 2>&1 || RUN="bunx"
echo "Using: $RUN"
Major versions are pinned (knip@5, jscpd@4, madge@8) so results stay stable.
Read the target project's package.json to understand it:
cat package.json
Note these details for validation:
next, react, vue, angular in dependenciesbun.lockb or "bun" in scripts"lint": "next lint" → eslint is used"test": "bun test --preload ./preload.ts" → preload.ts is usedls *.config.* tsconfig.json 2>/dev/nullRun each tool ONE TIME with the exact commands below. If a tool fails, report the error and move on.
$RUN knip@5 --reporter json --no-progress 2>&1 | head -500
Flags explained:
--reporter json - Machine-readable output--no-progress - Disable dynamic terminal updates (required for non-TTY)Parse the JSON output for:
files array - Unused filesissues[].dependencies - Unused dependenciesissues[].devDependencies - Unused devDependenciesissues[].exports - Unused exportsissues[].unlisted - Unlisted dependencies (false positives for framework-provided packages)$RUN madge@8 --circular --json --extensions ts,tsx --ts-config tsconfig.json --no-spinner src 2>&1
Flags explained:
--circular - Find circular dependencies--json - Machine-readable output--extensions ts,tsx - Only analyze TypeScript files--ts-config tsconfig.json - Use project's tsconfig for path resolution--no-spinner - Disable progress spinnersrc - Analyze the src directoryOutput: Returns [] if no circular deps, or array of dependency chains.
$RUN jscpd@4 src --min-lines 10 --min-tokens 100 --reporters json --silent --gitignore --max-size 500kb -o /tmp/jscpd-report 2>&1
Then read the report:
cat /tmp/jscpd-report/jscpd-report.json | head -200
Flags explained:
--min-lines 10 - Minimum 10 lines to count as duplicate (default 5 is too noisy)--min-tokens 100 - Minimum 100 tokens (default 50 is too noisy)--reporters json - JSON output--silent - No progress output--gitignore - Respect .gitignore--max-size 500kb - Handle larger files (default 100kb skips many files)-o /tmp/jscpd-report - Write to temp dir, not projectParse the report for:
statistics.total.clones - Number of duplicate blocksstatistics.total.duplicatedLines - Total duplicated linesduplicates array - Specific duplicate pairs with file paths and line rangesAfter running all tools, validate each finding using Grep to filter false positives.
# Check if package is imported anywhere
rg "from ['\"]package-name" src/
# Check if used in scripts
grep "package-name" package.json
Classify as:
# Check if file is imported anywhere
rg "from.*filename" src/
# Check if referenced in configs
grep -r "filename" *.config.* tsconfig.json package.json 2>/dev/null
Classify as:
## Code Cleanup Analysis (Validated)
### High Confidence - Safe to Remove
| Item | Type | Verification |
|------|------|--------------|
| react-icons | dependency | 0 imports in src/, not in scripts |
| src/components/OldComponent.tsx | file | 0 imports found |
### Circular Dependencies
[List any chains found by madge]
### Duplicate Code
[List significant duplicates from jscpd, skip test files and docs]
### Filtered Out (Not Issues)
- `eslint`: Used by `next lint` script
- `server-only`: Provided by Next.js
- `preload.ts`: Used by `bun test --preload` script
If user wants to proceed:
AskUserQuestion to confirm which items to removetrash command to delete unused files (not rm)bun install to update lockfilebun run typecheck to verify no breakageeslint, eslint-config-next → used by next lint scriptserver-only → provided by Next.js, shows as "unlisted" but is validpostcss, autoprefixer → used by Next.js CSS processingapp/ with special names (layout, page, loading, error) → framework conventionspreload.ts → used by bun test --preload@types/* packages → Bun provides built-in types@faker-js/faker, @testing-library/* → only in test files is OK@radix-ui/* packages → installed by CLI but component not yet usedCLAUDE.md <-> GEMINI.md duplication → intentionalnpx claudepluginhub zcaceres/skills --plugin qualityFetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.