Configuration
Configuration File
Create a .jscpd.json file in your project root to configure jscpd:
{
"threshold": 0,
"reporters": ["html", "console"],
"ignore": ["**/__snapshots__/**", "**/node_modules/**"],
"absolute": true,
"minLines": 5,
"minTokens": 50
}
CLI Options
| Option | Description | Default |
|---|---|---|
-V, --version | Output the version number | - |
-l, --min-lines | Minimum size of duplication in code lines | 5 |
-k, --min-tokens | Minimum size of duplication in code tokens | 50 |
-x, --max-lines | Maximum size of source in lines | 1000 |
-z, --max-size | Maximum size of source in bytes (e.g. 1kb, 1mb, 120kb) | 100kb |
-t, --threshold | Threshold for duplication, in case duplications >= threshold jscpd will exit with error | null |
-c, --config | Path to config file (default is .jscpd.json in scanned <path>) | null |
-i, --ignore | Glob pattern for files to exclude from duplication detection | null |
--ignore-pattern | Ignore code blocks matching the regexp patterns | null |
-r, --reporters | Reporters or list of reporters separated with comma to use | time,console |
-o, --output | Path for reports | ./report/ |
-m, --mode | Mode of quality of search: strict, mild, weak | mild |
-f, --format | Format or formats separated by comma to detect (e.g. php,javascript,python) | all formats |
-p, --pattern | Glob pattern to file search (e.g. **/*.txt) | - |
-b, --blame | Blame authors of duplications (get information about authors from git) | false |
-s, --silent | Do not write detection progress and result to console | false |
--store | Custom store (e.g. --store leveldb, useful for big codebases) | null |
--store-path | Directory to use for store cache (e.g. --store-path /tmp/jscpd-cache, useful for parallel runs) | .jscpd/ |
-a, --absolute | Use absolute path in reports | false |
-n, --noSymlinks | Don't use symlinks for detection in files | false |
--ignoreCase | Ignore case of symbols in code (experimental) | false |
-g, --gitignore | Ignore all files from .gitignore file | false |
--formats-exts | List of formats with file extensions (e.g. javascript:es,es6;dart:dt) | null |
--formats-names | List of formats with specific filenames (e.g. makefile:Makefile,GNUmakefile;docker:Dockerfile) | null |
-d, --debug | Show debug information, not run detection process (options list and selected files) | false |
-v, --verbose | Show full information during detection process | false |
--list | Show list of total supported formats | false |
--skipLocal | Skip duplicates in local folders, just detect cross folders duplications | false |
--exitCode | Exit code to use when code duplications are detected | 0 |
--noTips | Do not print tips and promotional messages after detection | false |
--skipComments | Ignore comments during detection (alias for --mode weak) | false |
-h, --help | Display help for command | - |
Examples
Basic scan
jscpd ./src
With pattern matching
jscpd --pattern "**/*.ts" ./src
Multiple reporters
jscpd --reporters html,json,console ./src
Custom threshold
Fail if duplication exceeds 5%:
jscpd --threshold 5 ./src
Ignore specific patterns
jscpd --ignore "**/*.test.ts,**/__mocks__/**" ./src
Skip comments (weak mode)
Use --skipComments as a shorthand for --mode weak:
jscpd --skipComments ./src
Map filenames to formats
For extensionless files like Makefile and Dockerfile:
jscpd --formats-names "makefile:Makefile,GNUmakefile;docker:Dockerfile" ./src
Custom LevelDB cache path
When running multiple jscpd processes in parallel:
jscpd --store leveldb --store-path /tmp/jscpd-cache ./src
Suppress tips in CI
Tips are automatically suppressed when --silent is active. To suppress manually:
jscpd --noTips ./src
Show debug information
jscpd --debug ./src
Show full information during detection
jscpd --verbose ./src
Cross-folder detection only
jscpd --skipLocal /path/to/folder1/ /path/to/folder2/
Ignore case in code
jscpd --ignoreCase ./src
Don't follow symlinks
jscpd --noSymlinks ./src
Ignore blocks by regexp pattern
jscpd --ignore-pattern "import.*from\s*'.*'" ./src
Package.json Configuration
You can also configure jscpd in your package.json:
{
"jscpd": {
"threshold": 0,
"reporters": ["html", "console"],
"ignore": ["**/node_modules/**"],
"absolute": true,
"gitignore": true
}
}
Modes
The --mode option controls detection quality:
strict— use all types of symbols as token, skip only blocks marked as ignoredmild— skip blocks marked as ignored and new lines and empty symbols (default)weak— skip blocks marked as ignored and new lines and empty symbols and comments
Cross-Format Detection
jscpd v4.2+ supports cross-format detection for multi-block file types:
- Vue SFC (
.vue) —<script>,<template>,<style>blocks tokenized separately - Svelte (
.svelte) — script and style blocks tokenized independently - Astro (
.astro) — frontmatter and template sections tokenized independently - Markdown (
.md) — fenced code blocks tokenized by language
This means a <script> block in a .vue file can be matched against a .ts file, and a fenced Python code block in Markdown can match a .py file.
Breaking Change for Vue Users
Vue files are no longer tokenized as markup. Each block uses its resolved sub-format (javascript, typescript, css, scss, etc.). Any tooling that relied on .vue clones being reported under markup must be updated.
Shebang Detection
jscpd can detect duplications in script files that have no file extension by reading the #! shebang line:
| Interpreter | Detected as |
|---|---|
bash, sh, zsh, fish, dash, ksh | shell |
python, python3, python2 | python |
node, nodejs | javascript |
ruby | ruby |
perl | perl |
php | php |
lua | lua |
tclsh, wish | tcl |
Rscript | r |
groovy | groovy |
swift | swift |
kotlin | kotlin |
Both direct (#!/usr/bin/bash) and env-mediated (#!/usr/bin/env python3) shebangs are supported. Version suffixes are stripped automatically (python3.11 → python).
Ignored Blocks
Mark blocks in code as ignored:
/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */
<!--
// jscpd:ignore-start
-->
<meta data-react-helmet="true" name="theme-color" content="#cb3837"/>
<link data-react-helmet="true" rel="stylesheet" href="https://static.npmjs.com/103af5b8a2b3c971cba419755f3a67bc.css"/>
<!--
// jscpd:ignore-end
-->