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.
$ npx -y skills add kucherenko/jscpd --agent claude-code
Repo: kucherenko/jscpd
What's inside
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.
Documentation: https://jscpd.dev
jscpd reads code the way its language defines it, not as plain text. Each of the 224 formats is tokenized with its own comment and string syntax, so # in Python, -- in SQL or ' in Visual Basic opens a comment only where the language says so. JavaScript, TypeScript, JSX and TSX go through the oxc parser, which handles template literals, regular expressions, JSX and decorators, and can erase TypeScript-only syntax so a .ts file matches its .js twin. Vue, Svelte, Astro, Markdown and Razor files are split into their embedded languages first, and each block is tokenized as the language it contains. Identifiers, keywords and literals are classified, which is what lets the renamed-clone pass replace names while keeping keywords in place.
On that token stream jscpd runs the Rabin-Karp algorithm to find duplicated blocks across files. Opt-in passes extend it to blocks that differ only in names or values (Type-2) and to copies with a few edited lines or the same function structure (Type-3), each reported with its kind and a similarity score. See How detection works.
# macOS / Linux
curl -fsSL https://jscpd.dev/install.sh | bash
# Windows (PowerShell)
irm https://jscpd.dev/install.ps1 | iex
# No install — run once with npx (Node.js)
npx jscpd .
Then scan a project:
jscpd /path/to/code
| Method | Command | Notes |
|---|---|---|
| npm | npm install -g jscpd | Installs the jscpd command; prebuilt binary, no Node.js at runtime |
npm (cpd command) | npm install -g cpd | Same binary, exposed as cpd |
| PyPI | pip install jscpd | Platform wheels with both commands; also pipx install jscpd, uv tool install jscpd, or uvx jscpd . to run without installing |
| Cargo | cargo install jscpd | Builds from crates.io; installs both jscpd and cpd |
| Homebrew | brew install jscpd | macOS / Linux |
| Nix | nix run github:kucherenko/jscpd -- /path/to/code | Or nix profile install github:kucherenko/jscpd |
| Docker | docker run --rm -v "$PWD:/src" ghcr.io/kucherenko/jscpd . | Multi-arch image built from the release binaries |
- uses: kucherenko/jscpd@v5
with:
threshold: 5
Uploads SARIF results to GitHub Code Scanning by default. See CI & Pre-Commit Hooks for all inputs and outputs.
| Document | Description |
|---|---|
| Rust engine | Installation, CLI reference, reporters, baseline, summary, complexity, dashboard, blame, config file |
| AI-Ready | AI reporter, agent skills, MCP server |
| Programming API | Rust API (cpd-finder crate) |
| CI & Pre-Commit Hooks | GitHub Action, Docker image, pre-commit hooks |
| Packages | npm packages and crates that make up a release |
| Supported formats | All 224 formats with their file extensions |
| Runnable demos | One fixtures/<feature>-demo/ directory per feature, each README lists the commands with their expected output |
jscpd v5 is a Rust engine that ships as a self-contained binary — no runtime required — under two npm names (jscpd installs the jscpd command, cpd installs cpd), on PyPI, crates.io, Homebrew, Nix, Docker, and as a GitHub Action.
--cross-formats groups to match clones across JavaScript and TypeScript--ignore-identifiers, --ignore-literals and --ignore-annotations find blocks that differ only in names, literal values or annotations, reported as renamed (see docs)--max-gap-lines N merges a copy with a few inserted or changed lines into one similar clone with a similarity score; --similarity 0.85 compares whole JavaScript/TypeScript functions by syntax-tree structure, so renames and scattered edits are still caught (see docs)exact, renamed or similar in the console, JSON (kind, similarity, method), XML, HTML, Xcode, SARIF (jscpd/duplicate-code, jscpd/renamed-code, jscpd/similar-code) and Code Climate output; default runs report only exact clones and are unchanged--kind — keep only the clone kinds you care about: --kind renamed, or --kind gap,ast for near-miss clones only. Statistics and --threshold follow the filter; a kind whose detector is off is a warning, an unknown kind an error (see docs)console, console-full, json, xml, csv, html, markdown, badge, sarif, codeclimate, openmetrics, ai, xcode, threshold, silent--baseline .jscpd-baseline.json with --fail-on-new-clones[=N] tolerates legacy clones and fails the build on regressions; --baseline-from-ref origin/main does the same without a committed file (see docs)--format, a missing scan path and a reporter that cannot write its file exit 1 instead of passing with an empty report; --fail-on-empty fails a scan that analyzed no files (see Exit codes)codeclimate (gl-code-quality-report.json) and openmetrics (jscpd-metrics.txt) plug into artifacts:reports--blame --reporters console-full)--history — duplication trend over git history: jscpd src --history v5.0.0..HEAD scans every commit in the range and prints a sparkline, a per-commit table with the change between points, the overall trend, and how far --threshold could be tightened (see docs)--dead-code — find code nothing runs, not just code written twice: unused files, exports, declarations and imports across JavaScript, TypeScript and Python. Builds the import graph from your entry points (package.json, pyproject.toml, framework conventions) and walks it, so dead code cascades — a helper whose only caller is dead is reported too. Every finding carries a confidence score and the reasons it might be wrong. Also ships standalone as basta (see docs)--summary — codebase summary: top files and folders by tokens, lines, size, and a complexity estimate — refactoring hotspots straight from the scan (see docs)--complexity — the complexity ranking alone, without clone detection: most complex files and folders from one tokenizing pass, in the console, ai or json (see docs)--health — one 0-100 health score with a grade, from the share of code that is duplicated, dead, or concentrated in complex files; size-aware, calibrated on 42 open-source projects, and extensible with coverage, test or security metrics through --health-input. Console badge, JSON and an SVG badge (see docs)--dashboard — the whole picture on one screen, under the health badge: project size, duplication by clone kind with the most duplicated files, the most complex files, and dead code by category for JavaScript, TypeScript and Python (see docs)--mcp — built-in MCP server over stdio with fully described tools: point your AI assistant at the binary and it can check snippets for duplication against your codebase, or find structurally similar functions with a similarity argument (see docs)--skip-local — report only clones that cross the scan roots: with jscpd packages/api packages/web --skip-local, pairs inside one of the two trees are dropped and only api-to-web duplication remains--skip-isolated — ignore duplication between monorepo folders owned by different teams (--skip-isolated "packages/team-a|packages/team-b")--workers — control parallelism for file tokenization and detection (default: all CPU cores).jscpd.json, .config/jscpd.json, or the jscpd key in package.json--follow-symlinks — v4 followed them by default. With the flag, a file reached through a link is reported by the path it was found at, and a file reachable through several paths is counted once--no-tips, CI or JSCPD_NO_TIPS switch them off everywhereSee the Rust docs for the full CLI reference and rust/CHANGELOG.md for release notes.
jscpd v4 (TypeScript engine, Node.js API, LevelDB/Redis stores) is maintained on the master-v4 branch and published as jscpd@4 / the latest-4 dist-tag. README-v4.md describes it in one page (install, CLI, API, packages, maintenance policy); the same content is at https://jscpd.dev/getting-started/v4.
| Package | Registry | Description |
|---|---|---|
| jscpd | npm | Installs the jscpd command (prebuilt binary via platform packages) |
| cpd | npm | Installs the cpd command (same binary) |
FAQ
jscpd is a Claude Code plugin with 3 hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. It includes codebase-refactoring, dry-refactoring, jscpd. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it