Share an Istanbul / nyc coverage report
nyc report --reporter=html produces the single most useful coverage artifact
in the JavaScript ecosystem: a summary table you can sort by branch coverage,
and behind every row a page with the uncovered lines highlighted in red and
the uncovered branches marked with I and E.
It is also a folder of several hundred files. So it never leaves the machine
that produced it, and the conversation about coverage happens over a
text-summary paste that says Branches: 71.4% and nothing about which
branches.
Publish the tree
npx nyc report --reporter=html --reporter=text-summary # → coverage/
Or straight from the runner:
npx jest --coverage --coverageReporters=html
npx vitest run --coverage # v8 or istanbul provider
Drag coverage/ (or a zip of it) into the app:
index.htmlbecomes the report body — the sortable summary.- Every per-file page,
base.css,prettify.js,sorter.jsandblock-navigation.jsupload as assets, and their relative references are rewritten to the uploaded copies. - Scripts run inside a sandboxed iframe (
allow-scripts, noallow-same-origin), so column sorting and the next/prev-uncovered keyboard navigation still work.
The drill-down is the whole point of the Istanbul reporter, and it survives the trip.
From CI
npx nyc report --reporter=html
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html coverage/index.html \
--arg title "Coverage — $GITHUB_REF_NAME" '{title: $title, html: $html}')"
PATCH the same report id every run and the URL in your README always shows current coverage, with a revision per run behind it. "Did this PR drop coverage?" becomes a diff instead of a spreadsheet of past percentages.
Run the step with if: always() — a run that failed its coverage threshold is
exactly the run whose report someone needs to read.
What review adds
- Anchored threads on the file that lost coverage, not on the percentage. See commenting on HTML.
- Revisions, so a slow slide from 84% to 71% is visible as a trend rather than discovered during a postmortem.
- Access per report — private, team, domain-gated, or named reviewers. See the sharing model.
Limits
- Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total. A very large monorepo tree can approach the 500-file cap — publish per package if it does.
- 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.