npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

coverage-insights

v0.3.26

Published

Per-test coverage analysis for Vitest, Jest, and Gradle/JVM projects — find redundant tests, fragile lines, and coverage gaps.

Downloads

2,601

Readme

coverage-insights

Per-test coverage analysis for Vitest, Jest, and Gradle/JVM projects — find redundant tests, fragile lines, and coverage gaps.

Runs your test suite once per test file, collects per-test line coverage, and cross-references it to surface actionable findings.

Installation

# Run once with npx
npx coverage-insights

# Or install globally
npm install -g coverage-insights

Requires Node.js 18+. Vitest or Jest must be installed in JS/TS projects. For Gradle projects, a JDK and Gradle wrapper (gradlew) are required.

Usage

Run from your project root:

coverage-insights [options]

Options

| Flag | Default | Description | |------|---------|-------------| | --root=<path> | cwd | Project root to analyse | | --out=<path> | coverage-insights/ | Output directory for JSON and HTML report | | --no-html | — | Skip generating the HTML report | | --threshold=<0-1> | 0.9 | Jaccard similarity threshold for high-overlap pairs | | --low-coverage=<0-100> | 80 | Line coverage % below which a file is flagged | | --top=<n> | all | Limit each section to top N findings | | --file=<glob> | all | Only run tests matching this pattern | | --config=<path> | auto | Path to vitest/jest config file | | --runner=vitest\|jest\|gradle | auto | Force a specific runner (otherwise auto-detected) | | --concurrency=<n> | auto | Max parallel test runs | | --integration | off | Include integration tests (Gradle only; classes named *IT, *IntegrationTest, etc. are skipped by default) |

Examples

# Basic run (HTML report generated by default)
coverage-insights

# Analyse a specific subdirectory
coverage-insights --root=./packages/my-package

# Only run tests matching a pattern
coverage-insights --file="src/auth/**"

# Limit output to top 20 findings per section
coverage-insights --top=20

# Skip HTML report
coverage-insights --no-html

Gradle / JVM projects

coverage-insights auto-detects Gradle projects by looking for build.gradle.kts or build.gradle in the project root. JaCoCo is used for coverage — if it is not already configured in your build, the runner injects it automatically via a Gradle init script.

# Auto-detected from build.gradle.kts
coverage-insights

# Force Gradle runner explicitly
coverage-insights --runner=gradle

# Limit to a specific module (substring match on module path)
coverage-insights --runner=gradle --file=application

Requirements:

  • JDK on PATH (JAVA_HOME set)
  • Gradle wrapper (./gradlew) in the project root, or gradle on PATH
  • Multi-module projects: settings.gradle.kts or settings.gradle with include(...) entries

Standard Gradle projects (JUnit 5 / KoTest)

Supported out of the box. Tests are discovered and run in isolation one at a time, each in its own Gradle invocation. JaCoCo coverage is collected per test and aggregated at the end.

Supported test engines: JUnit 5 (Jupiter) and KoTest.

Play Framework projects (JUnit 4)

Play Framework projects use JUnit 4 and have a different source layout (app/ rather than src/main/java/). Both are handled automatically.

Because Play Framework's heavy classloading makes repeated per-test JVM startups impractical, coverage-insights uses batch mode: a single Gradle invocation runs all tests and a JUnit 4 RunListener dumps per-test JaCoCo exec data after each test case. The results are then converted to per-test JSON coverage files without spawning additional JVMs.

On the first run, a small listener JAR is compiled from bundled Java source and cached at ~/.coverage-insights/listener.jar. Subsequent runs reuse the cached JAR (invalidated by SHA-256 hash if the source changes).

Note: If your project overrides jacocoClasspath (e.g. to pin a specific JaCoCo version), the standard jacocoAnt Gradle configuration may be empty. coverage-insights falls back to resolving JaCoCo jars from the buildscript classpath automatically.

Known limitations specific to batch mode:

  • JUnit 4 only — JUnit 5 / KoTest tests will not produce per-test output in batch mode
  • In multi-module projects, each subproject's batch conversion only sees that subproject's own compiled classes

General known limitations

  • Maven is not supported (Gradle only)
  • Branch coverage is not reported — JaCoCo's bytecode-level branch model doesn't map to the Istanbul format used internally
  • The --file flag filters by module name substring, not a file glob (e.g. --file=application runs only the :application module)

Output

Results are written to coverage-insights/ (or your --out path):

  • report.html — interactive HTML report
  • test-line-map.json — raw per-test line coverage data, keyed by "<file> > <test name>"
  • coverage-summary.json — aggregate coverage summary (line %, function %, per file)

Report sections

| Section | What it shows | |---------|--------------| | Consolidation candidates | Tests in the same describe block with identical line coverage — candidates for it.each or merged assertions | | High-overlap pairs | Test pairs sharing a high proportion of covered lines — one may be redundant | | Zero-contribution tests | Tests whose every covered line is also covered by a single larger test | | Hot lines | Source lines covered by an unusually high number of tests | | Fragile lines | Source lines covered by exactly one test | | Uncovered functions | Functions never called during the test run | | Low coverage files | Source files below the line coverage threshold |

Licence

MIT