Coverage comes from V8 86,723 itself: the runner turns on the engine's built-in counters, reads the raw report when the process exits and maps it back to your source, so there is no instrumentation step and no nyc 5,759 in the dependency tree. It is stability 1, experimental, on Node 25 and 26, hence the --experimental- prefix.
$ node --test --experimental-test-coverage --test-coverage-include="src/cart.js" ℹ start of coverage report ℹ ---------------------------------------------------------- ℹ file | line % | branch % | funcs % | uncovered lines ℹ ---------------------------------------------------------- ℹ src | | | | ℹ cart.js | 73.33 | 85.71 | 75.00 | 12-15 ℹ ---------------------------------------------------------- ℹ all files | 73.33 | 85.71 | 75.00 | ℹ ---------------------------------------------------------- ℹ end of coverage report |
| Coverage report for src/cart.js |
Lines say which statements ran, and 12-15 names the ones that did not. Branches is strictest and most useful: 85.71% means one arm of an if or one ?? fallback was never taken even though its line executed, so a file can sit at 100% lines and still have untested behavior.
Without --test-coverage-include the report covers every file the tests loaded, node_modules included; only loaded files appear at all, so a module no test imports is invisible. Thresholds turn the report into a gate: --test-coverage-lines, --test-coverage-branches and --test-coverage-functions each take a percentage, and missing one prints Error: 85.71% branch coverage does not meet threshold of 90%. and exits non-zero. Exclude unreachable code — a Windows-only branch in a suite on Linux — with /* node:coverage disable */ … /* node:coverage enable */.
For CI, add the lcov reporter alongside the human one, each with its own destination: --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info. Create coverage/ first: the reporter opens the file but will not make its directory. Aim for high branch coverage on business logic and accept low numbers on glue code; 100% mostly buys tests written to satisfy the counter.