HTML reporter
-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
jscpd . -r html --output report
HTML report saved to report/jscpd-report.html
{
"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:
| Section | What it holds |
|---|---|
| Dashboard | Total files, total lines of code, number of clones, and duplicated lines with the duplication in percent |
| Formats with duplications | One 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 format | Every 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 |
| Footer | The 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:
- uses: kucherenko/jscpd@v5
with:
reporters: console,html
upload-report: true
With the binary in any workflow:
- run: jscpd . -r console,html --output report
- uses: actions/upload-artifact@v4
if: always()
with:
name: jscpd-report
path: report/jscpd-report.html
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.
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.