Skip to content
Development
Skill

/codebase-refactoring

Three-part workflow to improve overall codebase health with jscpd — find and fix duplicated code, find and remove or refactor dead code, then find and simplify the largest/most complex files. Starts from --dashboard/--health to prioritize and ends by re-measuring the score.

From plugin
jscpd
6.5k5 skills

Claude Code

$ npx -y skills add kucherenko/jscpd --skill codebase-refactoring --agent claude-code

SKILL.md

codebase-refactoring.SKILL.md
name: codebase-refactoring
description: Three-part workflow to improve overall codebase health with jscpd — find and fix duplicated code, find and remove or refactor dead code, then find and simplify the largest/most complex files. Starts from --dashboard/--health to prioritize and ends by re-measuring the score.

codebase-refactoring

A guided pass over a codebase's three biggest maintenance costs — duplicated code, dead code, and complexity — using jscpd to find each and a strategy to fix it. Use this skill when asked to "clean up", "improve", "refactor" or "pay down tech debt in" a codebase, rather than to fix one specific bug.

Start here: measure, then prioritize

npx jscpd --health --reporters ai <path>
health 74 B (duplication 75, dead-code 72, complexity 76; 93 code lines)

The health score is a weighted mix of three sub-scores, each a share of the code lines — high is good, 100 is clean. The lowest of the three names where the codebase actually hurts most; if it isn't the order below, do that dimension first instead. `n/a` on a dimension (e.g. `dead code n/a`) means jscpd could not measure it — dead-code detection needs JavaScript, TypeScript or Python to be a real share of the code — skip that step rather than treating it as clean.

For the full picture behind that score — largest duplicated formats, most complex files, largest dead-code findings, all in one screen — run `npx jscpd --dashboard` instead. Its `console` output (the default) is the only reporter with that per-file detail; `--reporters ai` on `--dashboard` prints the same one-line summary shown above, not the breakdown, so don't reach for it expecting more than the score. Use `--reporters json` on `--dashboard` if you need the detail in a parseable form.

The three passes below are otherwise independent and safe to run in any order; **duplication → dead code → complexity** is the default because fixing duplication first means step 2 isn't wasting effort tracing call sites that a later extract-function pass will move anyway, and clearing dead code before step 3 means the files ranked for simplification are ones actually worth simplifying, not ones about to be deleted.

Step 1 — Duplicated code

npx jscpd --reporters ai --summary <path>

Find and read each clone, decide whether it is a real copy worth merging, and apply the matching refactoring strategy (extract function, parameterize, extract a shared module or constant, or a base class/template for structural duplication). Full guided workflow, triage rules for renamed/near-miss clones, and worked examples per clone kind:

→ **[dry-refactoring](../dry-refactoring/SKILL.md)** — run this now, then come back here for steps 2 and 3. Its own `--summary` hotspot ranking is the same one the health score's duplication dimension reads from, so a file it flags as a duplication hotspot is the same file that dragged the score down.

Step 2 — Dead code

npx jscpd --dead-code --reporters ai <path>
basta dead code report — 18 findings across 30 files (22.1% of 272 lines)
Confidence is 0-100; anything below 90 has a listed reason it may be wrong. Verify a finding before deleting the code.
unused-file typescript/src/legacy-export.ts:1:1 confidence=95 typescript/src/legacy-export.ts is never imported and is not an entry point
unused-export typescript/src/invoice.ts:21:17 confidence=85 exported function `renderReceipt` is never imported
unused-symbol typescript/src/invoice.ts:29:10 confidence=90 function `describeTotal` is never used in typescript/src/invoice.ts
unused-import typescript/src/invoice.ts:2:10 confidence=100 `roundToCents` is imported but never used

This is a graph traversal from the project's entry points (`package.json` `main`/`bin`/`exports`/`scripts`, `pyproject.toml` scripts, framework conventions, or `--entry <glob>`), not a reference count — a helper whose only caller is itself dead is reported too, so deleting one finding can make another true that wasn't reported yet. Covers JavaScript, TypeScript, JSX, TSX, Vue, Svelte, Astro and Python.

The four categories, and what to do with each

| Category | Meaning | Usual fix | |----------|---------|-----------| | `unused-file` | Never imported anywhere, not an entry point | Delete the file | | `unused-export` | Exported, but no other file imports it | Delete it, or drop the `export` keyword if something in the same file still uses it | | `unused-symbol` | A module-private declaration nothing in its own file references | Delete it | | `unused-import` | Imported but never referenced in the file | Delete the import line |

Workflow

1. Run with `--reporters ai` (add `--dead-code-categories` to focus on one category, `--include-tests` if test-only usage shouldn't count as "used", `--include-entry-exports` to also flag an entry file's own unused exports, normally excluded since its whole surface is the public API) 2. Sort by confidence, high to low. Everything is 0-100; below 90 the finding carries a stated reason it might be wrong — `eval`/`getattr` calls, decorators the analyzer doesn't recognize, a wildcard re-export, the name showing up only inside a string literal, or a file elsewhere that failed to parse (see `statistics.unparsedFiles` in the JSON report). Read the reason before deleting; `--min-confidence` (default 60) only sets the floor for what's reported, it doesn't make a low-confidence finding safe 3. For each finding above your comfort threshold, confirm it by hand — grep the symbol name across the repo (dynamic access, a string-based router, a template file jscpd doesn't parse can all hide a real use) — then apply the fix from the table above 4. Run the project's own test suite and build after each batch of deletions, not only jscpd's re-run: dead-code analysis proves nothing *reaches* the code from an entry point, not that removing it can't break a build step 5. Re-run `--dead-code` afte

Read more
@kucherenko
Ships withjscpd

Duplicate code detector for 220+ languages — plus dead code, complexity hotspots, duplication and health trends over git history, and one health score for the whole codebase.

Stars on GitHub

Momentum

stars in total
6.5k
Star history of kucherenko/jscpd on GitHub, a chart by star-history.com

Other skills on jscpd.

code-migration

code-migration

Move code from one implementation to another function by function, tests first and code second, and check two implementations of…

@kucherenko@kucherenkoInstall Skill
compare-codebases

compare-codebases

Compare two folders function by function with jscpd --compare, in the same language or across languages, and explain the result.…

@kucherenko@kucherenkoInstall Skill
dry-refactoring

dry-refactoring

Guided workflow to eliminate copy-paste duplication detected by jscpd. Refactor exact, renamed and near-miss clones using extract…

@kucherenko@kucherenkoInstall Skill
jscpd

jscpd

Copy-paste detector for 220+ languages. Detect exact, renamed and near-miss duplicated code, measure duplication percentages, and…

@kucherenko@kucherenkoInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about codebase-refactoring.

Which coding agents can use codebase-refactoring?
codebase-refactoring installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.