CI & Hooks

Use jscpd in CI

Run jscpd in GitHub Actions, GitLab CI, and other CI systems to enforce duplication thresholds.

GitHub Action

The jscpd-copy-paste-detector GitHub Action runs jscpd in your CI workflow. It installs the Rust engine, runs detection, uploads SARIF to GitHub Code Scanning, and optionally uploads the report as an artifact.

Basic Usage

.github/workflows/jscpd.yml
name: Duplication Check

on: [push, pull_request]

jobs:
  jscpd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: kucherenko/jscpd@master

This scans the entire repository with default settings and uploads SARIF results to GitHub Code Scanning.

Fail on Threshold

Set threshold to fail the build when duplication exceeds a percentage:

- uses: kucherenko/jscpd@master
  with:
    threshold: 5

The workflow fails if more than 5% of the code is duplicated.

Action Inputs

InputDescriptionDefault
pathPaths to scan (space-separated).
configPath to .jscpd.json config file
min-tokensMinimum tokens for a clone50
min-linesMinimum lines for a clone5
max-linesMaximum lines per block
modeDetection mode: mild, weak, strictmild
formatComma-separated formats to check
ignoreComma-separated glob patterns to ignore
ignore-patternComma-separated regex patterns to skip
reportersComma-separated reportersconsole
outputOutput directory for file reportersreport
thresholdMax duplication % before exit 1
blameEnrich clones with git blame datafalse
exit-codeExit with code when duplicates found (true or integer)
patternGlob pattern for file search
max-sizeSkip files larger than SIZE
skip-localSkip clones in same directoryfalse
ignore-caseIgnore case of symbols (experimental)false
follow-symlinksFollow symbolic linksfalse
no-gitignoreDon't respect .gitignore filesfalse
absoluteUse absolute paths in reportsfalse
formats-extsCustom format-to-extension mappings
formats-namesCustom format-to-filename mappings
versionjscpd version to installlatest
install-prefixInstallation directory for the binary
skip-installSkip installation (binary already present)false
extra-argsAdditional arguments passed to jscpd
upload-reportUpload report directory as artifactfalse
upload-sarifUpload SARIF to GitHub Code Scanningtrue

Action Outputs

OutputDescription
duplication-percentagePercentage of duplicated code found
clones-foundNumber of clone pairs found
duplicated-linesNumber of duplicated lines
total-linesTotal lines scanned
files-countNumber of source files scanned
report-pathPath to the output directory
sarif-pathPath to the SARIF report file
exit-codeExit code from jscpd

Examples

Scan specific directories with threshold

- uses: kucherenko/jscpd@master
  with:
    path: src/lib src/utils
    threshold: 3
    ignore: "**/*.test.*,**/*.spec.*"

Use a config file

- uses: kucherenko/jscpd@master
  with:
    config: .jscpd.json
    upload-report: true

Multi-reporter with artifact upload

- uses: kucherenko/jscpd@master
  with:
    reporters: console,json,html,sarif
    output: jscpd-report
    upload-report: true

Pin a specific version

- uses: kucherenko/jscpd@master
  with:
    version: "5.0.9"

Skip install (binary already in image)

- uses: kucherenko/jscpd@master
  with:
    skip-install: true

Use outputs in subsequent steps

- uses: kucherenko/jscpd@master
  id: jscpd

- name: Check results
  if: steps.jscpd.outputs.duplication-percentage > 5
  run: |
    echo "Duplication is ${{ steps.jscpd.outputs.duplication-percentage }}%"
    echo "Found ${{ steps.jscpd.outputs.clones-found }} clones"

GitLab CI

Use jscpd in GitLab CI with a simple pipeline job:

.gitlab-ci.yml
jscpd:
  stage: test
  image: node:20
  before_script:
    - npm install -g jscpd@5
  script:
    - jscpd --threshold 5 --reporters console,sarif .
  artifacts:
    paths:
      - report/

Generic CI

Any CI system that can run shell commands works with jscpd:

npm install -g jscpd@5
jscpd --threshold 5 ./src

The --threshold flag makes jscpd exit with code 1 when duplication exceeds the specified percentage, which causes CI builds to fail.

Tips

  • Use --reporters console,sarif in CI to get both console output and SARIF for code scanning platforms
  • Use --threshold to set a failure threshold — the process exits with code 1 if exceeded
  • Use --ignore to exclude generated files, test fixtures, or vendor directories
  • For large repos, use the Rust engine (jscpd@5 / cpd) — it runs 24-37x faster, keeping CI times low
  • Consider --format to limit detection to specific languages during CI, with a full scan in a scheduled job