How to view LCOV coverage reports online (no setup required)
LCOV reports from Jest, Vitest, Istanbul, and coverage.py are just text files. Here's how to read them without installing anything.
Every major test framework — Jest, Vitest, Istanbul, pytest-cov, gcov — can export coverage data in LCOV format. The output is a plain text file, usually named lcov.info, sitting somewhere in your coverage/ directory after a test run. Reading it is the hard part: the raw format is designed for machine consumption, not humans. This guide shows you how to turn that file into a readable coverage report in seconds, without installing any additional tooling.
What is an LCOV file?
LCOV is a coverage data format originally developed as a front-end to gcov, GCC's built-in coverage tool. It has since become the de facto interchange format for coverage data across languages and frameworks because it is simple, text-based, and well-supported by CI systems like Codecov, Coveralls, and GitHub's coverage annotations.
A typical lcov.info file looks like this:
TN: SF:src/utils/format.ts FN:3,formatDate FN:12,formatCurrency FNDA:5,formatDate FNDA:0,formatCurrency FNF:2 FNH:1 DA:3,5 DA:4,5 DA:12,0 DA:13,0 LF:4 LH:2 end_of_record
Each record describes one source file. The key line prefixes are: SF (source file path), FN (function definition with line number), FNDA (function hit count), DA (line number and hit count), BRDA (branch data), and the summary totals LF/LH (lines found/hit) and FNF/FNH(functions found/hit). Reading this raw is tedious — a viewer translates it into percentages, color-coded tables, and sortable file lists.
How to generate an LCOV report
Jest and Istanbul
Jest uses Istanbul under the hood. Add --coverage and set the reporter to include lcov:
// jest.config.js
module.exports = {
collectCoverage: true,
coverageReporters: ["lcov", "text"],
coverageDirectory: "coverage",
};Run npx jest and you will find coverage/lcov.info after the test run completes.
Vitest
// vitest.config.ts
export default {
test: {
coverage: {
provider: "v8", // or "istanbul"
reporter: ["lcov", "text"],
},
},
};Run npx vitest run --coverage. The output lands at coverage/lcov.info.
Python (pytest-cov / coverage.py)
# Install once pip install pytest-cov # Run tests with LCOV output pytest --cov=src --cov-report=lcov:coverage/lcov.info
Or with coverage.py directly:
coverage run -m pytest coverage lcov -o coverage/lcov.info
Go
go test ./... -coverprofile=coverage.out # Convert Go's profile format to LCOV: go install github.com/jandelgado/gcov2lcov@latest gcov2lcov -infile=coverage.out -outfile=coverage/lcov.info
How to view the report
The traditional approach is genhtml — an LCOV command-line tool that convertslcov.info into a multi-page HTML report. It works well but requires installing the lcov package (brew install lcov, apt install lcov) and navigating to the generated HTML locally. In a CI environment you typically upload the file to Codecov or Coveralls instead.
For a faster workflow — especially when debugging coverage gaps during local development or reviewing a colleague's lcov.info without cloning the repo — a browser-based viewer is significantly faster. Drop the file, see the result immediately.
quickhelp.dev's LCOV Coverage Viewer accepts any lcov.info file (drag and drop or paste the text directly), parses it entirely in your browser, and renders a sortable table of all files with line, function, and branch coverage percentages. Files below 80% are highlighted in amber; below 60% in red. No upload, no account, no install.
What to look for in a coverage report
Once you have the report open, sort by coverage ascending. The lowest-covered files are your highest-risk areas — not because low coverage is always bad, but because it surfaces files that have never been tested at all (0% line coverage) vs files that are tested but have untested branches.
Pay attention to the difference between line coverage and branch coverage. A file can have 100% line coverage and 50% branch coverage — every line was executed, but some conditional paths were never taken. Branch coverage gaps in validation logic, error handling, and authentication code are the most dangerous.
Function coverage is the simplest metric: it tells you which functions were never called by tests. Dead code and unused utility functions show up here as 0% function coverage. Before deleting them, verify they are not called at runtime via a path your tests don't cover.
Using LCOV in CI
Most CI providers natively consume lcov.info. GitHub Actions with thecodecov/codecov-action will automatically find and upload coverage files; Coveralls uses coveralls-lcov. For coverage gates — failing the build when coverage drops below a threshold — most frameworks support this natively:
// jest.config.js — fail if overall line coverage drops below 80%
module.exports = {
coverageThreshold: {
global: {
lines: 80,
functions: 80,
branches: 70,
},
},
};For local inspection of any lcov.info — your own, from a PR, or from a CI artifact — open it in the LCOV viewer for an instant readable summary.