Getting Started

Installation

Get started with jscpd.

jscpd is a self-contained native binary — no Node.js runtime required. Install via curl, PowerShell, npm, pip, cargo, Homebrew, or Nix.

Looking for v4? The TypeScript version is maintained on the master-v4 branch and installs with npm install -g jscpd@4. See the v4 page for its CLI, API and packages, and the Migration Guide for what changed.

Using curl (macOS & Linux)

One command installs the cpd binary for your platform:

Terminal
curl -fsSL https://jscpd.dev/install.sh | bash
This installer requires a POSIX shell, so it is macOS and Linux only. On Windows, bash is either unavailable or resolves to WSL — in which case it installs the Linux binary inside the WSL filesystem rather than under your Windows user profile. Use the PowerShell installer below instead.

Using PowerShell (Windows)

Installs a native Windows executable — no Node.js, Git Bash, or WSL required:

PowerShell
irm https://jscpd.dev/install.ps1 | iex

By default it installs jscpd.exe (and the cpd.exe alias) to %USERPROFILE%\.local\bin, and prints the command to add that directory to your PATH. Both x64 and ARM64 are detected automatically.

To pass options, run the script rather than piping it:

PowerShell
&([scriptblock]::Create((irm https://jscpd.dev/install.ps1))) -Version 5.1.0 -Prefix C:\tools

Supported switches: -Version, -Prefix, -Force (overwrite an existing binary), -DryRun.

By default the shell installer puts jscpd (and the cpd alias) in ~/.local/bin, and prints the command to add that directory to your PATH. Install to a custom directory:

Terminal
curl -fsSL https://jscpd.dev/install.sh | bash -s -- --prefix ~/.local/bin

Install a specific version:

Terminal
curl -fsSL https://jscpd.dev/install.sh | bash -s -- --version 5.2.1

Both installers download from GitHub Releases (primary) and fall back to the npm registry. Between them they cover macOS (arm64/x64), Linux (x64 and arm64, glibc and musl), and Windows (x64 and ARM64 MSVC).

The shell installer verifies every download before it installs anything: release archives are checked against the checksums.txt published with the release, npm tarballs against the integrity hash the registry reports. A mismatch aborts the install. Pass --version for a reproducible install — without it the newest release is resolved at run time.

Using npm

The npm package installs a native binary for your platform:

Terminal
npm install -g jscpd@5

Using cargo

If you have Rust installed, install directly from crates.io:

Terminal
cargo install jscpd

This installs both the jscpd and cpd commands.

Using pip, pipx or uv

The PyPI package ships the same prebuilt binary as platform wheels, so Python projects can install jscpd without Node.js:

Terminal
pip install jscpd
# or, isolated:
pipx install jscpd
uv tool install jscpd

Run without installing:

Terminal
uvx jscpd /path/to/source

Installs both the jscpd and cpd commands. For a Node-free pre-commit hook, use language: python with additional_dependencies: ['jscpd==5.2.1'].

Using Homebrew

If you use Homebrew on macOS or Linux:

Terminal
brew install jscpd

Using Nix

Install with Nix (installs both jscpd and cpd commands):

Terminal
nix profile install github:kucherenko/jscpd

Or run without installing:

Terminal
nix run github:kucherenko/jscpd -- /path/to/source

Using Docker

A multi-arch (amd64/arm64) distroless image is published to GitHub Container Registry with every release (v5.1.2+). Mount the project at /src:

Terminal
docker run --rm -v "$PWD:/src" ghcr.io/kucherenko/jscpd

Tags: latest, 5, 5.1, and the exact version. The image contains only the static binary — --blame and --baseline-from-ref need git, which is not included. On Linux hosts, add --user "$(id -u):$(id -g)" so report files are owned by you rather than root.

Using npx (No Installation)

Run jscpd directly without installing (downloads the native binary on first run):

Terminal
npx jscpd@5 /path/to/source

Using yarn

Terminal
yarn global add jscpd@5

Using pnpm

Terminal
pnpm add -g jscpd@5

Platform Binaries

Direct downloads are available for each platform:

PlatformPackage
macOS Apple Siliconjscpd-darwin-arm64
macOS Inteljscpd-darwin-x64
Linux x64 (glibc)jscpd-linux-x64-gnu
Linux ARM64 (glibc)jscpd-linux-arm64-gnu
Linux x64 (musl/Alpine)jscpd-linux-x64-musl
Linux ARM64 (musl/Alpine, v5.1.2+)jscpd-linux-arm64-musl
Windows x64jscpd-windows-x64-msvc
Windows ARM64 (v5.1.0+)jscpd-windows-arm64-msvc

Basic Usage

Scan a directory

Run jscpd on your source code directory:

Terminal
jscpd /path/to/source

Use pattern matching

Scan specific file patterns:

Terminal
jscpd --pattern "src/**/*.js"

Generate HTML report

Create an HTML report of duplications:

Terminal
jscpd /path/to/source --reporters html

Configuration

Create a .jscpd.json file in your project root:

.jscpd.json
{
  "threshold": 0,
  "reporters": ["html", "console"],
  "ignore": ["**/__snapshots__/**", "**/node_modules/**"],
  "absolute": true
}

Rust Crate API

jscpd provides Rust crates for programmatic integration:

Cargo.toml
[dependencies]
cpd-finder = "0.1"
src/main.rs
use cpd_finder::orchestrate;

fn main() {
    let result = orchestrate(&["./src".into()], &Default::default());
    println!("Found {} clones", result.statistics.total_clones);
}

See Rust Crates for the full crate reference, or MCP Server to expose jscpd to AI assistants with jscpd --mcp.