Copy/Paste Detector for Source Code

Agents copy. Reviewers miss it. Your build shouldn't. jscpd reads each of 224 languages by its own syntax, finds exact, renamed and near-miss duplicates, and fails the build when they cross your threshold. One native binary, no runtime: a 159 MB codebase scans in 3.4 seconds. It also finds dead code, ranks complexity and scores codebase health, speaks MCP, ships agent skills, and has a reporter LLMs can afford to read.
Terminal
$npx jscpd .
Node.js 20+, any OS, nothing installed globally
// Your code deserves better than copy/paste chaos
$jscpd./src
→ Finding duplicates...
✓ Found 90 clones · 54.4% duplication

Built for codebases where agents write code

Agents repeat helpers. Each diff reads fine on its own, so review misses it. A failing build doesn't.
    Gate it
    jscpd . --threshold 3

    Runs in pre-commit and CI. "An agent will argue a comment, but a failing build just stops it." — @nark3d

    Set up the gate →
    Let the agent check itself
    jscpd --mcp

    MCP server built into the binary. Claude, Cursor or any MCP client can check for clones before writing more.

    MCP server docs →
    Teach it to refactor
    npx skills add kucherenko/jscpd

    Skills that run the whole workflow: find duplicates, extract them, remove dead code, simplify complex files, then check the numbers improved.

    Install the agent skill →
    Feed the LLM, not the context window
    jscpd . --reporters ai

    About 79% fewer tokens than the default reporter. Pipe it straight into your agent loop.

    See the token benchmark →
    Know where to start
    jscpd . --dashboard

    One screen: a health score on top, then duplication, the most complex files and dead code. Fix the worst first.

    Project dashboard →
    Find what nothing runs
    jscpd . --dead-code

    Unused files, exports and imports in JavaScript, TypeScript and Python — and in Rust, read from the compiler's own diagnostics — each with a confidence score. --complexity ranks the most complex files without running clone detection.

    Health score and dead code →
    Watch the trend
    jscpd . --history v5.0.0..HEAD

    One scan per commit, shown as a chart and a table in your terminal. See whether agents add duplication faster than you remove it, and how far you can tighten the threshold.

    Duplication trend over history →

Finds the copies that don't look like copies

Exact copies are the easy case. jscpd also reports renamed and near-miss clones, each tagged with its kind and a similarity score. Default runs are unchanged; the extra kinds are opt-in flags.
    Exact clones, by default
    jscpd .

    Type-1: identical tokens. Whitespace, layout and comments don't count. Every run reports these, starting from --min-tokens 50 and --min-lines 5.

    Type-1 clones →
    Renamed clones
    jscpd . --ignore-identifiers --ignore-literals

    Type-2: the same code with different variable names or literal values. --ignore-annotations also drops @Decorator lines. Keywords keep their meaning, so return never matches retry. Reported as renamed.

    Type-2 clones →
    Near-miss clones
    jscpd . --max-gap-lines 2 --similarity 0.7

    Type-3: a copy with a few inserted or changed lines (--max-gap-lines N), or a JavaScript/TypeScript function with the same structure (--similarity RATIO, compared by syntax tree). Reported as similar with a score.

    Type-3 clones →
One function, four ways to copy it. Exact by default, renamed with --ignore-identifiers, an inserted line with --max-gap-lines 2, scattered edits with --similarity 0.7.

How teams wire it

Four places, one binary. Each takes about a minute.
    1. Pre-commit

    Block the commit before the clone lands.

    .husky/pre-commit
    npx jscpd --threshold 3 .
    Pre-commit and Husky setup →
    1. CI gate

    Fail the pull request when duplication crosses the line.

    # .github/workflows/jscpd.yml
    - uses: kucherenko/jscpd@v5
      with:
        threshold: 3
    
    GitHub Action, GitLab CI, generic CI →
    1. Agent loop

    Give the agent the same detector, over MCP.

    // MCP client config
    { "mcpServers": { "jscpd": {
        "command": "jscpd", "args": ["--mcp", "."] } } }
    
    Connect Claude, Cursor, or Copilot →
    1. Agent skill

    Teach the agent the workflow, not just the tool: scan, refactor duplicates, remove dead code, simplify complex files, check the health score improved.

    installs the jscpd, dry-refactoring and codebase-refactoring skills
    npx skills add kucherenko/jscpd
    Skills for Claude, Copilot, Gemini, Cursor →

Core

Detection refined since 2013, now a native Rust engine
    Since 2013

    A decade refining duplicate detection, now rewritten in Rust for native speed.

    How detection works →
    Speaks 224 languages

    JavaScript, Python, Java, Go, Rust, C++, TypeScript, Ruby... If you can write it, we can scan it.

    View supported formats →
    Blazingly fast™

    A Rust engine with parallel detection across format groups. A 159 MB codebase takes 3.4 seconds. No Node.js runtime, just one native binary.

    See benchmarks →
    CLI first

    One command, everywhere: your laptop, CI/CD, that ancient Jenkins server nobody wants to touch.

    Get started →
    Reports you can show

    HTML, JSON, XML and README badges. Make technical debt visible (and slightly embarrassing).

    Explore reporters →
    Thresholds and baselines

    Set a threshold and fail the build, or commit a baseline and fail only on clones added since.

    Configure thresholds →
    Cross-format detection

    Vue, Svelte, Astro and Markdown files are tokenized per block, so a <script> in a .vue file can match a .ts file. --cross-formats "js-ts" compares related formats in one pool, catching clones between .js and .ts.

    Cross-format benchmark →
    Git blame

    --blame shows who wrote each clone, from git history, so you know who to ask before you refactor.

    All CLI options →
    10M+ npm downloads / month

    One of the most trusted tools in the ecosystem. Join the developers who rely on jscpd every day.

    View on npm →
    Trusted in research

    54 papers, theses and patents use or cite jscpd: a measurement instrument in ACM TOSEM, two ICLR papers and an 832-million-line industrial dataset, a baseline for new detectors, a component of five patented systems.

    jscpd in research →
    Written about, not just installed

    54 verified blog posts, talks and case studies: real configs and numbers from teams wiring jscpd into CI gates, pre-commit hooks and AI agent loops.

    jscpd in articles →

Integrations

Plug it into the tools you already run
    GitHub Action

    uses: kucherenko/jscpd@v5 scans the repository, fails on threshold and uploads SARIF to Code Scanning. No install step.

    GitHub Action docs →
    Pre-commit Hooks

    Works with the pre-commit framework, Husky or a plain shell hook in .git/hooks. Blocks the commit when duplication exceeds the threshold.

    Pre-commit docs →
    SARIF / Code Scanning

    --reporters sarif writes a SARIF file that GitHub Code Scanning renders as inline alerts on the pull request.

    SARIF reporter docs →
    GitLab CI

    The codeclimate reporter feeds GitLab Code Quality and openmetrics feeds its metrics reports, so duplication shows on the merge request.

    GitLab CI docs →
    Programmable

    Embed detection in your own tools with the Rust crates (cpd-finder, cpd-core), or run the CLI and parse its JSON from any language.

    View API documentation →
    Trending repos, analyzed

    How much copy/paste ships in GitHub's trending repos? A daily pipeline runs jscpd on each and publishes the results.

    See today's results →

Fresh from GitHub Trending

Every day we run jscpd v5 over GitHub's trending repositories and publish how much copy/pasted code they ship: clone counts, duplication rates and the largest duplicated blocks.

Developers Are Talking

Real mentions from the community on X
Horatio Thomas
Horatio Thomas@horatioecthomas

One of the most important tools you can add to CI when building with AI: github.com/kucherenko/jscpd

なかつがわ
なかつがわ@someone7140

へぇ 「jscpd v5 は Rust 製で速い。 26.7 万行 / 127ms。CI コストは実質ゼロ」

Nathan Broadbent
Nathan Broadbent@ndbroadbent

I highly recommend jscpd: github.com/kucherenko/jscpd Can’t live without this in my projects now

Peter Steinberger
Peter Steinberger@steipete

TIL: jscpd

mono
mono@_mono

npmjs.com/package/jscpd がDartコードのコピペ検出も対応してることを dart-lang/sdk の issue で知って試したら普通に動いた( ´・‿・`) 利用例: `jscpd . --pattern "**.dart" --min-lines 20`

Cory House
Cory House@housecor

One of my favorite tools during a code audit is jscpd. It detects copy/pasted code. In a codebase I’m currently reviewing, nearly half of the JS is duplicated! jscpd lists the specific duplicated spots so we can consider a cleanup.

Matt Pocock
Matt Pocock@mattpocockuk

Get AI to reduce duplicated code, reduce the jscpd number

Peter Steinberger
Peter Steinberger@steipete

I du regular sweeps with jscpd, ran a Socrates analysis yesterday and it was in the single digits. Could purge more, but writing overly generic code has its own problems.

nark3d
nark3d@nark3d

Same here, jscpd and the linter both sit in our CI gate. The thing that surprised me is it holds up better with agents than a review comment does. An agent will argue a comment, but a failing build just stops it, so the duplication never gets in.

高橋 俊 | CTO - ZENSHIN
高橋 俊 | CTO - ZENSHIN@suguru_takaha4

jscpd というコピペコードを検出する静的解析ツールいいかもしれない 結局コード品質を担保するにはAIに逐一指示するというアプローチよりは静的解析ツールとかでガチガチに縛ってしまった方が気持ち的に大胆にリファクタリングしやすい

Maximilian
Maximilian@_maxscn

just added a jscpd pre-commit hook and why did i not do this ages ago

Cory House
Cory House@housecor

Problem: You want to find copy/pasted code. Solution: jscpd. It finds copy/pasted code in over 150 languages. I just ran this command on a JS project: npx jscpd --ignore "**/node_modules/**" It found over 6,000+ lines of duplicated code.

Chris Cheney
Chris Cheney@_cheney

I break my specs into directed acyclic graphs in order to identify what work depends on other work and which tasks can be worked in parallel. I also run jscpd in pre-commit which helps cleanup duplicate code and interfaces. See my GitHub DAG project as an example of this

.
.@sjallatak

a good way to minimize slop in a typescript codebase is a forced validation command of knip, jscpd and linter of your choice. the more static validation you have the better.

HARUKI / UNCHAIN Community Lead
HARUKI / UNCHAIN Community Lead@haruki_web3

重複コードを消すツール! これも良さそう!!

matt sephton
matt sephton@gingerbeardman

Been experimenting with jscpd to spot similar code that I might be able to refactor, with the goal of simplifying and optimising and hopefully shave some bytes off my apps. Works with 150+ formats.

nark3d
nark3d@nark3d

I’ve got jscpd in the pre-commit hook for the same reason. It catches the duplicate before commit instead of in review, and review misses copy-paste because each diff reads fine alone. Gets more useful the more an agent repeats the same helper.

BudgetIce
BudgetIce@BudgetIce37955

知らせる層は knip(デッドコード)と jscpd(重複)。 こっちは止めずに、気づかせるだけの設定 あとは"入れて終わり"にしたくなかったので、既存のコードで溜まってた借金を返すEpicも立てて、子Issue10件で完走

harjot.co
harjot.co@harjjotsinghh

jscpd is genuinely one of those quietly-everywhere dev tools, congrats on the milestone. a small OSS project really can outlast flashier ones…

Cory House
Cory House@housecor

Problem: Your code base probably contains a lot of copy/pasted code, but it’s hard to find. Solution: jscpd jscpd is a command line tool that finds copy/pasted code and reports specific duplicated lines. Works for over 150 languages.

Contributors

jscpd is built by its contributors. Bug reports, formats, reporters, docs — every one of them is on this list.

Supported by

JetBrains and Anthropic give jscpd their tools through their open source programmes, and both are open to other maintainers.
JetBrains logo.Claude logo.