Skip to content
Development
Skill

/jscpd

Copy-paste detector for 220+ languages. Detect exact, renamed and near-miss duplicated code, measure duplication percentages, and find refactoring hotspots with the codebase summary.

From plugin
jscpd
6.2k2 skills
Install
$ npx -y skills add kucherenko/jscpd --skill jscpd --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/jscpd

Context preview

The summary Claude sees to decide when to auto-load this skill.

Copy-paste detector for 220+ languages. Detect exact, renamed and near-miss duplicated code, measure duplication percentages, and find refactoring hotspots with the codebase summary.

SKILL.md

jscpd.SKILL.md
name: jscpd
description: Copy-paste detector for 220+ languages. Detect exact, renamed and near-miss duplicated code, measure duplication percentages, and find refactoring hotspots with the codebase summary.

jscpd

Copy-paste detector for programming source code, supports 220+ languages. Use this skill to run jscpd and understand its output.

Quick Start

# Run with ai reporter (compact output optimized for agents)
npx jscpd --reporters ai <path>

# With ignore patterns
npx jscpd --reporters ai --ignore "**/node_modules/**,**/dist/**" <path>

# Scope to specific formats
npx jscpd --reporters ai --format "javascript,typescript" <path>

# Second pass, noisier: copies that only differ in names and values (Type-2, "renamed").
# Review each hit before acting on it.
npx jscpd --reporters ai --ignore-identifiers --min-tokens 70 <path>

# Third pass, noisier still: copies with a few edited lines or the same function
# structure (Type-3, "similar"). Keep the settings tight.
npx jscpd --reporters ai --max-gap-lines 1 --similarity 0.85 <path>

# Where to refactor first: clone list plus a hotspot summary
npx jscpd --reporters ai --summary <path>

AI Reporter Output Format

The `ai` reporter produces compact, token-efficient output designed for agent consumption:

Clones:
src/ foo.ts:10-25 ~ bar.ts:42-57
src/utils/helpers.ts:100-120 ~ src/utils/other.ts:5-25
src/cart/ basket.js:1-9 ~ cart.js:1-9 (renamed)
src/api/ save-account.js:1-12 ~ save-user.js:1-11 [~0.91 gap]
src/billing/ credit-note.js:1-19 ~ invoice.js:1-17 [~0.75 ast]
---
5 clones · 4.2% duplication

Each line represents one clone pair:

  • **Same file**: `path/file.ts 10-25 ~ 45-60` (shared path shown once)
  • **Same directory**: `shared/prefix/ file-a.ts:10-25 ~ file-b.ts:42-57` (common prefix factored out)
  • **Different paths**: `path/a.ts:10-25 ~ path/b.ts:42-57`

A suffix tells the **kind** of clone; no suffix means an exact copy:

  • `(renamed)`: the two blocks differ only in identifier names, literal values or annotations (Type-2). Only appears with `--ignore-identifiers`, `--ignore-literals` or `--ignore-annotations`.
  • `[~0.91 gap]`: two exact clones merged across up to `--max-gap-lines` unmatched lines (Type-3). The number is matched tokens over the merged span.
  • `[~0.75 ast]`: two functions whose syntax-tree structure overlaps at least `--similarity` (Type-3). The number is the structural similarity, names and literal values do not count.

Options

| Option | Description | |--------|-------------| | `--reporters ai` | Use the AI-optimized reporter (compact clone list for agents) | | `--reporters html` | Generate HTML report | | `--reporters json` | Output JSON report | | `--min-tokens N` | Minimum tokens to consider a duplication (default: 50) | | `--min-lines N` | Minimum lines to consider a duplication (default: 5) | | `--threshold N` | Exit with error if duplication % exceeds N | | `--ignore "glob"` | Ignore patterns (comma-separated) | | `--format "list"` | Limit to specific languages (e.g. `typescript,javascript`) | | `--cross-formats "groups"` | Detect clones across related formats (e.g. `javascript,typescript` or the `js-ts` preset) | | `--ignore-identifiers` | Treat all identifiers as equal, so blocks that differ only in variable, function or type names match (Type-2, reported as `renamed`) | | `--ignore-literals` | Treat all string literals as equal and all numeric literals as equal (Type-2) | | `--ignore-annotations` | Drop `@Name` / `@Name(...)` annotations and decorators before matching, in languages where `@` means one (Type-2) | | `--max-gap-lines N` | Merge clones of one file pair separated by at most N unmatched lines into one `similar` clone (Type-3, default: 0 = off) | | `--similarity RATIO` | Report JavaScript/TypeScript function pairs whose syntax-tree similarity reaches RATIO, in `(0, 1]`, as `similar` clones (Type-3, default: 1 = exact only) | | `--summary` | Append a codebase summary: top files/folders by tokens, lines, size, complexity, with duplication share | | `--summary-top N` | Number of entries in each summary top list (default: 10) | | `--summary-by metric` | Summary ranking metric: `tokens`, `lines`, `size`, `complexity` (default: `tokens`) | | `--pattern "glob"` | Glob pattern to select files | | `--no-gitignore` | Do not respect `.gitignore` (it is respected by default) | | `--output "path"` | Directory to write reports to | | `--silent` | Suppress console output (useful with file reporters and `--output`) | | `--list` | List all supported formats and exit | | `--no-tips` | Disable tips in output (skipped automatically when stdout is not a TTY or `CI` or `JSCPD_NO_TIPS` is set) | | `--config "path"` | Path to .jscpd.json config file |

Clone Kinds: Exact, Renamed, Similar

By default jscpd reports **exact** clones only: the token sequences are identical (whitespace, layout and, depending on the mode, comments do not count). Two opt-in families widen the net. Run them as separate passes after the default scan, because they find more and longer clones and change what a "clone" means.

**These passes are noisy by design.** An exact clone is almost always a real copy. A renamed or similar clone is a *candidate*: the flags deliberately ignore the very things (names, values, a statement or two) that often make two blocks different in meaning. Expect false positives from:

  • boilerplate that is supposed to look alike: DTOs and models, config tables, enum-like maps, route or handler registrations, builders
  • test files: `describe`/`it` blocks, fixtures and setup code repeat the same shape on purpose
  • generated code, migrations, serializers, protocol bindings
  • language idioms: two `reduce` loops or two `switch` statements that share structure but not logic
  • small blocks: with `--ignore-identifiers` a 50-token block is mostly placeholders, so raise `--min-tokens`

Rules that keep the noise manageable:

  • Run them **after** the exact clones are handled, one family a
Read more
Ships withjscpd

Copy/paste detector for programming source code. 220+ formats, language-aware tokenization, exact, renamed and near-miss clones, Rust engine, self-contained binary, AI-ready with MCP server and token-efficient reporter.

Get the whole plugin
Stats
6,206
Stars
264
Forks
Active
Maintenance
Rust
Language
MIT
License
1d ago
Last commit
13y ago
Created

Repo: kucherenko/jscpd

Other skills on jscpd.