c8

Native V8 code coverage for Node.js, with Istanbul-compatible reports and zero build-step setup.

Tool
npm
v12.0.0
2,123 stars
ISC

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
58 /100 Fair
Development Activity 48
Maintenance 32
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
77 /100 Good
Architecture 88
Code Quality 78
Innovation 72
Learning Curve 70

c8 wraps a Node.js test run and captures code coverage directly from V8’s built-in inspector protocol, then converts that raw coverage data into Istanbul-format reports. Because it relies on Node’s native NODE_V8_COVERAGE instrumentation, there’s no separate compile-time instrumentation pass like older tools such as Istanbul/nyc required.

It also supports source-map remapping for TypeScript and JSX projects, per-file or global coverage-threshold enforcement via c8 check-coverage, and an experimental Monocart integration for byte-offset-based V8 reporters that skip the Istanbul conversion step entirely.

What You Get

  • Zero-instrumentation coverage collection driven directly by V8’s inspector protocol
  • Full Istanbul reporter compatibility (text, html, lcov, json, and any istanbul-reports plugin)
  • Built-in check-coverage command for enforcing line/branch/function/statement thresholds, globally or per file
  • Source-map remapping so coverage maps back to original TypeScript/JSX/pre-compiled sources
  • --all flag to surface files that were never loaded by the test run as 0% covered
  • Inline ignore comments (/* c8 ignore next */, ignore start/stop) for excluding unreachable branches

Common Use Cases

  • Adding coverage reporting to a Node.js test suite (mocha/tape/ava/etc.) without a babel or ts-node instrumentation step
  • Enforcing a minimum coverage threshold in CI via c8 --check-coverage --lines 100 npm test
  • Auditing “full” project coverage with --all to catch files that tests never even load
  • Remapping coverage from compiled TypeScript output back to original source files for accurate reporting
  • Regenerating reports from previously captured coverage data with c8 report

Under The Hood

Architecture

bin/c8.js is the CLI entry point built on yargs (lib/parse-args.js’s buildYargs), which parses instrumentee vs. instrumenter args (hideInstrumenteeArgs/hideInstrumenterArgs) to separate c8’s own flags from the wrapped script’s flags, then uses foreground-child to spawn the target script with NODE_V8_COVERAGE pointed at a temp directory so V8 writes raw coverage JSON as a side effect. After the child exits, lib/commands/report.js’s outputReport builds a Report (lib/report.js) that reads every coverage file from the temp directory through test-exclude-filtered globbing, merges them into an istanbul-lib-coverage map (optionally remapping through source maps via v8-to-istanbul and lib/source-map-from-file.js), and hands that map to istanbul-lib-report’s context for any istanbul-reports plugin to render. lib/commands/check-coverage.js reuses the same Report class to enforce thresholds instead of rendering output, so the whole tool is a thin orchestration layer around three swappable stages: collect via V8, merge/remap via Istanbul libraries, and report or threshold-check via pluggable reporters, with no custom instrumentation of its own.

Tech Stack

Plain JavaScript (no TypeScript at runtime, though index.d.ts ships hand-written types) targeting Node.js >=20.19/22.12/23 per the engines field. Core dependencies are yargs/yargs-parser for CLI parsing, foreground-child for spawning the instrumented process, find-up for locating .c8rc/.nycrc config files, and the Istanbul-ecosystem libraries (istanbul-lib-coverage, istanbul-lib-report, istanbul-reports, @istanbuljs/schema) plus v8-to-istanbul and @bcoe/v8-coverage for converting raw V8 coverage into Istanbul’s format. test-exclude handles include/exclude glob filtering, and an optional peer dependency on monocart-coverage-reports unlocks an alternate reporting pipeline. There’s no bundler or build step since it ships plain CommonJS files directly, and CI runs the test matrix across two Node major versions plus a dedicated Windows job via GitHub Actions.

Code Quality

The integration test suite spawns the actual c8 binary as a subprocess against fixtures and asserts against a large committed snapshot file using Mocha, chai, and chai-jest-snapshot — a genuine end-to-end testing strategy rather than mocked unit tests. A posttest script runs the zero-config standard linter, and a dedicated coverage script runs the suite through c8 itself for dogfooding. Error handling in the CLI entry point and check-coverage command is minimal but explicit, catching subprocess and report failures and setting process.exitCode accordingly. No automated type-checking is wired into CI despite the shipped index.d.ts, and GitHub Actions covers two Node versions plus a separate Windows job, giving reasonable but not exhaustive platform coverage.

API Design c8’s public surface is deliberately small: the CLI has one primary invocation shape plus a check-coverage/report subcommand pair, and the programmatic API (requiring the Report class directly) mirrors the CLI options as constructor fields, so there’s very little conceptual translation between CLI flags and library usage. Zero-instrumentation coverage collection is the project’s core ergonomic win over instrumentation-based tools like nyc, meaningfully lowering setup friction for TypeScript and ESM projects where source instrumentation is awkward. Documentation is thorough for a project this size, covering every flag and the ignore-comment syntax in the README, though it stops short of a full API reference for the Report class, whose surface is documented only through the shipped .d.ts file.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers