Reporters

The 15 reporters of jscpd, what each one writes, and which to pick for a terminal, a script, a merge request widget or a README.

Every reporter ships inside the jscpd binary, so there is nothing to install. -r (--reporters) takes a comma-separated list, console is the default, and the reporters that write files put them in --output, which is ./report/ unless you change it. The console reporters print to stdout, so one run can print to the terminal and write any number of files.

The reporters

ReporterWritesPick it when
consolethe terminalyou read the result where you ran it: the clones, then a table per format (the default)
console-full (aliases consoleFull, full)the terminalyou want the code of both copies under each clone; with --blame each line carries its author on both sides
aithe terminalan agent or an LLM reads the output: one line per clone and no code, about 79% fewer tokens than console
xcodethe terminala build log parser such as Xcode's turns path:line:column: warning: lines into warnings
silentthe terminalyou only want the one-line summary and the exit code
thresholdnothinga v4 config lists it; --threshold runs the same check on its own
jsonjscpd-report.jsona script reads the clones and the statistics
xmljscpd-report.xmla tool expects the PMD CPD XML format
csvjscpd-report.csvthe per-format statistics go into a spreadsheet
markdownjscpd-report.mdthe statistics table goes into a pull request comment or a wiki page
htmljscpd-report.htmla person reads the report in a browser
badgejscpd-badge.svg, jscpd-lines-badge.svga README shows the duplication
sarifjscpd-report.sarifGitHub code scanning or another SARIF consumer shows the clones on the diff
codeclimate (alias gitlab)gl-code-quality-report.jsonGitLab lists the clones in the Code Quality widget of a merge request (5.1.0+)
openmetricsjscpd-metrics.txtGitLab metrics reports or a Prometheus-style parser track the numbers (5.1.0+)

jscpd 5 has no time reporter: the timing line prints on its own, and a time entry left over from a v4 config is accepted and ignored.

Run it

Terminal
jscpd . -r console,json,html --output report

The console part prints first, then one line per file:

Found 3 clones.
JSON report saved to report/jscpd-report.json
HTML report saved to report/jscpd-report.html
time: 4.566ms

--no-colors drops the ANSI colors from the console reporters, which keeps a CI log readable. The same reporters in the config file:

.jscpd.json
{
  "reporters": ["console", "json", "html"],
  "output": "report"
}

What the terminal shows

The console reporter prints one header per clone, the two locations as [line:column - line:column], and a table per format. The header names the format and, when the clone is not an exact copy, its kind. On the fixtures/mcp-demo folder of the repository, with the flags that find renamed and near-miss clones:

Terminal
jscpd . --ignore-identifiers --ignore-literals --max-gap-lines 1 -r console
Clone found (javascript, similar (gap) ~0.95)
 - src/invoice.js [1:1 - 12:2] (12 lines, 197 tokens)
   src/print/invoice.js [1:1 - 13:2]
Clone found (javascript)
 - src/orders.js [1:1 - 12:2] (12 lines, 124 tokens)
   src/reports/orders.js [1:1 - 12:2]
Clone found (javascript, renamed)
 - src/returns.js [1:1 - 10:2] (10 lines, 104 tokens)
   src/shipping.js [1:1 - 10:2]
Found 3 clones.
time: 6.764ms

The table is shortened here: the real one has a row for every format in the scan, including the ones without clones (bash, markdown and python in this folder). console-full prints the same headers with the source lines of both copies underneath.

The ai reporter drops the table and the code and factors the common path prefix out of each pair. A renamed clone gets (renamed), a near-miss clone its similarity and the mechanism that found it, a semantic clone [~0.78 semantic]:

Terminal
jscpd . --ignore-identifiers --ignore-literals --max-gap-lines 1 -r ai
Clones:
src/ invoice.js:1-12 ~ print/invoice.js:1-13 [~0.95 gap]
src/ orders.js:1-12 ~ reports/orders.js:1-12
src/ returns.js:1-10 ~ shipping.js:1-10 (renamed)
---
3 clones · 17.7% duplication

On the repository's fixtures/ tree (132 files, 91 clones) this came to about 1,100 tokens against about 5,400 for console. AI token efficiency has a second measurement on the larger benchmark corpus.

xcode prints one line per clone in the shape build tools parse, and silent prints the summary line only:

src/invoice.js:1:0: warning: Found 11 lines (1-12) duplicated on file src/print/invoice.js (1-13)
src/orders.js:1:0: warning: Found 11 lines (1-12) duplicated on file src/reports/orders.js (1-12)
src/returns.js:1:0: warning: Found 9 lines (1-10) duplicated on file src/shipping.js (1-10)
Found 3 clones.
Duplications detection: Found 3 exact clones with 25(13.02%) duplicated lines in 9 (4 formats) files.

How kinds and gates show up

The kind of a clone, a baseline and --threshold reach each format differently. The exit code is the same for all of them, and jscpd writes the files before the gates run, so a failing job still has its reports.

ReporterKind of cloneNew against a baselineOver --threshold
console, console-fullin the header: renamed, similar (gap) ~0.95, similar (ast) ~0.75, semantic ~0.78[NEW] after the header and Found 3 clones (2 new).an ERROR: line, exit 1
ai(renamed), [~0.95 gap], [~0.75 ast], [~0.78 semantic]nothingexit 1
jsonkind, similarity, methodisNew per clone, newClones and newDuplicatedLines in the statisticsnothing in the file, exit 1
sarifthe rule idlevel errorevery result at level error
codeclimatecheck_nameseverity majorevery issue at major
openmetricsnothingjscpd_new_clones, jscpd_new_duplicated_linesnothing in the file
html, xml, csv, markdown, badge, xcode, silentnothingnothingnothing in the file

--kind narrows every reporter to the kinds you name, and the statistics follow the clones that are reported.

Other modes

The modes beside clone detection reuse the reporter names and write files of their own:

ModeReportersFiles
--compareconsole, console-full, json, markdown, htmljscpd-compare.json, jscpd-compare.md, jscpd-compare.html
--dashboardconsole, json, badge, markdown, htmljscpd-dashboard.json, jscpd-dashboard.md, jscpd-dashboard.html, jscpd-health-badge.svg
--healthconsole, ai, json, badge, markdown, htmljscpd-health.json, jscpd-health.md, jscpd-health.html, jscpd-health-badge.svg
--complexityconsole, ai, jsonjscpd-complexity.json