jscpd v4 (TypeScript / Node.js)

June 8, 2026 · View on GitHub

Copy/paste detector for programming source code. The TypeScript engine runs on Node.js and is published as jscpd on npm.

Installation

# npm
npm install -g jscpd

# npx (no install required)
npx jscpd /path/to/code

CLI Usage

jscpd [options] <path ...>

Options

OptionShortDescriptionDefault
--min-lines-lMinimum lines in a clone5
--min-tokens-kMinimum tokens in a clone50
--max-lines-xMaximum source file lines1000
--max-size-zMaximum source file size (e.g. 1kb, 1mb)100kb
--threshold-tDuplication percentage threshold (exit with error if exceeded)
--config-cPath to config file.jscpd.json in path
--ignore-iGlob patterns to exclude
--ignore-patternRegex patterns to ignore code blocks
--reporters-rReporters (comma-separated)time,console
--output-oOutput directory for file reporters./report/
--mode-mDetection mode: strict, mild, weakmild
--format-fFormats to check (comma-separated)all detected
--pattern-pGlob pattern for file search
--blame-bEnrich clones with git blame author dataoff
--silent-sSuppress console outputoff
--storeCustom store (e.g. leveldb for large repos)memory
--store-pathDirectory for store cache (parallel runs)
--absolute-aUse absolute paths in reportsoff
--noSymlinks-nDon't follow symlinksoff
--ignoreCaseIgnore case of symbols (experimental)off
--gitignoreRespect .gitignore files (default: enabled)on
--no-gitignoreDon't respect .gitignore files
--formats-extsCustom format-to-extension mapping (e.g. javascript:es,es6;dart:dt)
--formats-namesCustom format-to-filename mapping (e.g. makefile:Makefile;docker:Dockerfile)
--skipLocalSkip clones within the same directoryoff
--skipCommentsAlias for --mode weak (ignore comments)off
--noTipsSuppress tips and promotional messagesoff
--exitCodeExit code when clones detected
--debug-dShow debug info, don't run detectionoff
--verbose-vShow full info during detectionoff
--listList all supported formats and exit
--version-VPrint version
--help-hPrint help

Reporters

ReporterOutput
consoleClone list with per-format statistics table
consoleFullFull source snippets for each clone
jsonreport/jscpd-report.json
xmlreport/jscpd-report.xml
csvreport/jscpd-report.csv
htmlInteractive HTML report (via @jscpd/html-reporter)
markdownreport/jscpd-report.md
badgeSVG badges (via @jscpd/badge-reporter)
sarifSARIF output for GitHub Code Scanning (via jscpd-sarif-reporter)
aiToken-efficient output for LLM pipelines
xcodeXcode-compatible warnings
thresholdExit 1 if duplication exceeds --threshold
silentNo console output

You can also install third-party reporters as npm packages (e.g. jscpd-full-reporter).

Config File

Create .jscpd.json in the target directory:

{
  "path": ["./src"],
  "reporters": ["console", "json"],
  "minLines": 5,
  "minTokens": 50,
  "maxLines": 1000,
  "maxSize": "100kb",
  "threshold": 0,
  "format": ["javascript", "typescript"],
  "ignore": ["**/node_modules/**"],
  "gitignore": true,
  "mode": "mild",
  "absolute": false,
  "skipLocal": false,
  "skipComments": false
}

Detection Modes

ModeBehavior
strictAll tokens must match (including whitespace, newlines)
mildIgnore empty and newline tokens
weakIgnore comments, empty tokens, and newlines (--skipComments is an alias)

Examples

# Scan current directory
jscpd .

# Scan specific paths with options
jscpd --min-lines 10 --min-tokens 100 --reporters console,json,html ./src

# Scan only TypeScript files
jscpd --format typescript --pattern "**/*.ts" ./src

# Ignore directories
jscpd --ignore "**/dist/**,**/node_modules/**" .

# Skip clones within the same folder
jscpd --skipLocal .

# Use LevelDB store for large repos
jscpd --store leveldb /path/to/large/repo

# Configure LevelDB cache directory for parallel runs
jscpd --store leveldb --store-path /tmp/jscpd-cache /path/to/repo

Programming API

jscpd Promise API

import { IClone } from '@jscpd/core';
import { jscpd } from 'jscpd';

const clones: IClone[] = await jscpd([]);

jscpd with argv

import { IClone } from '@jscpd/core';
import { jscpd } from 'jscpd';

const clones: IClone[] = await jscpd(['', '', './fixtures', '-m', 'weak', '--silent']);

detectClones API

import { detectClones } from 'jscpd';

const clones = await detectClones({
  path: ['./src'],
  silent: true,
  format: ['javascript', 'typescript'],
  minLines: 5,
  minTokens: 50,
  mode: 'mild',
});

detectClones with custom store

import { detectClones } from 'jscpd';
import { IMapFrame, MemoryStore } from '@jscpd/core';

const store = new MemoryStore<IMapFrame>();

await detectClones({
  path: ['./src'],
}, store);

// Re-use the store for incremental detection
await detectClones({
  path: ['./src'],
  silent: true,
}, store);

Building custom tools

For deep customization, compose the lower-level packages:

  • @jscpd/core — Core detection algorithm, event emitter interface
  • @jscpd/tokenizer — Source code tokenization (224+ formats via reprism)
  • @jscpd/finder — File walking, clone detection, built-in reporters
  • @jscpd/leveldb-store — LevelDB persistent store for large repos
  • @jscpd/redis-store — Redis store for distributed/CI environments

Format Support

v4 supports 224 formats (verified via --list). Use jscpd --list to see the full list.

Cross-Format Detection

Vue SFC (.vue), Svelte (.svelte), Astro (.astro), and Markdown (.md) files are tokenized per-block/per-section, enabling duplicate detection across file types (e.g., a <script> block in a .vue file matching a .ts file).

Shebang Detection

Extensionless executable scripts are auto-detected by their shebang line (supports bash, python, node, ruby, perl, php, lua, tcl, R, groovy, swift, kotlin).

Custom Format Mapping

# Map extensions to formats
jscpd --formats-exts "javascript:es,es6;dart:dt" ./src

# Map specific filenames to formats
jscpd --formats-names "makefile:Makefile,GNUmakefile;docker:Dockerfile" ./src

Architecture

jscpd (CLI + API)
 ├── @jscpd/core        — Detection algorithm (Rabin-Karp), event system
 ├── @jscpd/tokenizer   — Source code tokenization (224+ formats via reprism)
 ├── @jscpd/finder      — File walking, orchestration, built-in reporters
 ├── @jscpd/html-reporter      — Interactive HTML report
 ├── @jscpd/badge-reporter     — SVG badge generation
 ├── @jscpd/sarif-reporter     — SARIF for GitHub Code Scanning
 ├── @jscpd/leveldb-store      — LevelDB persistent store
 └── @jscpd/redis-store        — Redis distributed store