Reporters

HTML reporter

One self-contained page with the statistics per format and the code of every clone, for reading a report in a browser.

-r html writes a page you open in a browser or attach to a CI job: four summary cards, a table of the formats, and every clone with its source behind a "Show code" button. Pick it when a person reads the report; a script is better off with the JSON reporter, and a merge request widget with SARIF or the CodeClimate format.

Run it

Terminal
jscpd . -r html --output report
HTML report saved to report/jscpd-report.html
.jscpd.json
{
  "reporters": ["console", "html"],
  "output": "report"
}

The output

jscpd-report.html is one file with its styles inline; the only external resource is the npm downloads badge in the footer. From top to bottom:

SectionWhat it holds
DashboardTotal files, total lines of code, number of clones, and duplicated lines with the duplication in percent
Formats with duplicationsOne row per format with files, lines, clones, duplicated lines and duplicated tokens, each count with its percentage, plus a total row; a format name links to its clones
One section per formatEvery clone as two locations, src/invoice.js (Line 1:1 - Line 12:2) and src/print/invoice.js (Line 1:1 - Line 13:2), with a "Show code" button that reveals the first fragment
FooterThe jscpd version that wrote the page

The page has no filter or sort controls, and it does not mark the kind of a clone or whether it is new against a baseline; the JSON and SARIF reports carry that.

Where it shows up

Upload the file as an artifact so a failing job still leaves it behind. With the GitHub Action, upload-report: true uploads the whole output directory:

.github/workflows/jscpd.yml
- uses: kucherenko/jscpd@v5
  with:
    reporters: console,html
    upload-report: true

With the binary in any workflow:

.github/workflows/jscpd.yml
- run: jscpd . -r console,html --output report
- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: jscpd-report
    path: report/jscpd-report.html
.gitlab-ci.yml
jscpd:
  script:
    - jscpd . -r console,html --output report
  artifacts:
    when: always
    paths:
      - report/jscpd-report.html

With gates

--threshold changes nothing in the page: jscpd writes the file, then checks the duplication and sets the exit code. --kind narrows the clone list to the kinds you name, and the statistics follow it. A baseline leaves the page as it is.

Options

The HTML reporter reads -o/--output only. CLI options lists it with the rest.

Other modes

With --compare, -r html writes jscpd-compare.html instead: a migration map that draws two folders as dependency graphs facing each other, with a bridge for every pair of functions that do the same job, and a table of the same pairs on a second tab. Like the clone report, it is one file.

Terminal
jscpd --compare python/ typescript/ -r html

Two live examples: a Python module halfway through its port to TypeScript and ten Tauri plugins compared across Android and iOS. Comparing two codebases explains how to read the map.

--dashboard writes jscpd-dashboard.html and --health writes jscpd-health.html under the same reporter name.

  • Reporters for the whole list and the files each one writes.
  • CI for complete workflows.