# Share a Rust Coverage Report — Tarpaulin or llvm-cov at a URL

Canonical: https://commareports.com/share-rust-coverage-report
Published: 2026-08-30

> cargo tarpaulin and cargo llvm-cov both write HTML that dies with the CI runner. Publish it: annotated source at a stable link, threads on the uncovered branch, a revision per run.

# Share a Rust coverage report

Rust's coverage story got good and stayed awkward to share. Both of the
tools people use produce a real HTML report, and both of them produce it
inside `target/` on whichever machine ran the tests.

## Two tools, two output shapes

```bash
# LLVM source-based — more accurate, writes a directory
cargo llvm-cov --html
# → target/llvm-cov/html/index.html + per-file pages

# tarpaulin — writes ONE self-contained file
cargo tarpaulin --out Html
# → tarpaulin-report.html
```

Use **`cargo llvm-cov`** when you care about the numbers being right: it
uses LLVM instrumentation and handles generics and macro expansion far
better than tarpaulin's instruction-counting approach.

Use **`cargo tarpaulin --out Html`** when you care about the report being
easy to move, because a single file publishes in one call with nothing to
upload alongside it.

## Publishing the tarpaulin single file

```bash
cargo tarpaulin --out Html || true

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 tarpaulin-report.html \
        --arg title "Coverage — $(git rev-parse --short HEAD)" \
        '{title: $title, html: $html}')"
```

One call, no assets. Use a [scoped token](/docs/api-tokens)
(`reports:write`) from CI secrets and `PATCH` a saved report id, so one
URL accumulates a revision per run instead of a new orphan link per build.

The `|| true` matters — tarpaulin runs your suite, so a failing test fails
the step. Add `if: always()` in GitHub Actions. See
[publishing from CI](/ci).

## Publishing the llvm-cov directory

```
target/llvm-cov/html/
├── index.html
├── coverage/…/src/lib.rs.html    # one page per source file
└── style.css
```

Drag that folder (or a zip of it) into
[Comma](https://commareports.com/): `index.html` becomes the report body,
the per-file pages upload alongside it, and relative references are
rewritten so the drill-down from summary to annotated source resolves.

From CI, the entry page goes in the `PATCH` body and the per-file pages go
up through `POST /api/v1/reports/$REPORT_ID/assets` as base64 — one call
per file, worth scripting once. See the [API reference](/docs/api).

## What the URL changes

- **The PR links the coverage.** Reviewers click instead of running
  `cargo llvm-cov` locally, which on a large workspace is not a quick
  thing to ask.
- **Review lands on the code.** Select the uncovered arm of a `match`,
  leave a thread — "this is the error path, it needs a test" — and it
  stays anchored there across runs. See
  [commenting on HTML](/comment-on-html).
- **Revision diffs beat the percentage.** Two runs, one diff, which lines
  changed coverage. A Rust workspace's coverage number moves for
  uninteresting reasons constantly; the diff doesn't.

## Who can see it

The coverage report **contains your source code**. Access is per report —
private, your team, any signed-in user with the link, or public — and team
or private is the right default for a private repo. Domain-gating is
Enterprise. See [sharing & access control](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** Tarpaulin inlines every covered source file, so a
  large workspace can exceed it — generate per-crate reports and publish
  the crates people review. Assets: 25 MB per file, 250 MB and 500 files
  total.
- **Scripts run, sandboxed** (`allow-scripts`, no `allow-same-origin`).
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited
revision history.

**[Publish a coverage report →](https://commareports.com/)**

### Related

- [Share a coverage report](/share-coverage-report) · [Share an lcov report](/share-lcov-report)
- [Share a Go test report](/share-go-test-report) · [Share a benchmark report](/share-benchmark-report)
- [Publish from CI](/ci) · [GitHub Actions HTML reports](/ci/github-actions-html-report)
