--- title: coverage | Config outline: deep --- # coverage {#coverage} You can use [`v8`](/guide/coverage.html#v8-provider), [`istanbul`](/guide/coverage.html#istanbul-provider) or [a custom coverage solution](/guide/coverage#custom-coverage-provider) for coverage collection. You can provide coverage options to CLI with dot notation: ```sh npx vitest --coverage.enabled --coverage.provider=istanbul ``` ::: warning If you are using coverage options with dot notation, don't forget to specify `--coverage.enabled`. Do not provide a single `--coverage` option in that case. ::: ## coverage.provider - **Type:** `'v8' | 'istanbul' | 'custom'` - **Default:** `'v8'` - **CLI:** `--coverage.provider=` Use `provider` to select the tool for coverage collection. ## coverage.enabled - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.enabled`, `--coverage.enabled=false` Enables coverage collection. Can be overridden using `--coverage` CLI option. ## coverage.include - **Type:** `string[]` - **Default:** Files that were imported during test run - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.include=`, `--coverage.include= --coverage.include=` List of files included in coverage as glob patterns. By default only files covered by tests are included. It is recommended to pass file extensions in the pattern. Patterns are matched against each file's path relative to the project root. A pattern with no glob wildcard is treated as a directory and matches everything inside it, so `include: ['src']` is equivalent to `include: ['src/**']`. See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples. ## coverage.exclude - **Type:** `string[]` - **Default:** : `[]` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=` List of files excluded from coverage as glob patterns. Patterns are matched the same way as [`coverage.include`](#coverage-include). See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples. ## coverage.clean - **Type:** `boolean` - **Default:** `true` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.clean`, `--coverage.clean=false` Clean coverage results before running tests. ## coverage.cleanOnRerun - **Type:** `boolean` - **Default:** `true` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.cleanOnRerun`, `--coverage.cleanOnRerun=false` Clean coverage report on watch rerun. Set to `false` to preserve coverage results from previous run in watch mode. ## coverage.reportsDirectory - **Type:** `string` - **Default:** `'./coverage'` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.reportsDirectory=` ::: warning Vitest will delete this directory before running tests if `coverage.clean` is enabled (default value). ::: Directory to write coverage report to. ## coverage.reporter - **Type:** `string | string[] | [string, {}][]` - **Default:** `['text', 'html', 'clover', 'json']` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.reporter=`, `--coverage.reporter= --coverage.reporter=` Coverage reporters to use. See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. See [`@vitest/istanbul-lib-report`](https://github.com/vitest-dev/istanbuljs/tree/main/packages/istanbul-lib-report/src/reports) for details about reporter specific options. The reporter has three different types: - A single reporter: `{ reporter: 'html' }` - Multiple reporters without options: `{ reporter: ['html', 'json'] }` - A single or multiple reporters with reporter options: ```ts { reporter: [ ['lcov', { 'projectRoot': './src' }], ['json', { 'file': 'coverage.json' }], ['text'] ] } ``` You can also pass custom coverage reporters. See [Guide - Custom Coverage Reporter](/guide/coverage#custom-coverage-reporter) for more information. ```ts { reporter: [ // Specify reporter using name of the NPM package '@vitest/custom-coverage-reporter', ['@vitest/custom-coverage-reporter', { someOption: true }], // Specify reporter using local path '/absolute/path/to/custom-reporter.cjs', ['/absolute/path/to/custom-reporter.cjs', { someOption: true }], ] } ``` You can check your coverage report in Vitest UI: check [Vitest UI Coverage](/guide/coverage#vitest-ui) for more details. ::: tip AI coding agents When Vitest detects it is running inside an AI coding agent, it automatically adds the `text-summary` reporter and sets `skipFull: true` on the `text` reporter to reduce output and minimize token usage. ::: ## coverage.reportOnFailure {#coverage-reportonfailure} - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.reportOnFailure`, `--coverage.reportOnFailure=false` Generate coverage report even when tests fail. ## coverage.allowExternal - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.allowExternal`, `--coverage.allowExternal=false` Collect coverage of files outside the [project `root`](/config/root). ## coverage.excludeAfterRemap - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.excludeAfterRemap`, `--coverage.excludeAfterRemap=false` Apply exclusions again after coverage has been remapped to original sources. This is useful when your source files are transpiled and may contain source maps of non-source files. Use this option when you are seeing files that show up in report even if they match your `coverage.exclude` patterns. ## coverage.skipFull - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.skipFull`, `--coverage.skipFull=false` Do not show files with 100% statement, branch, and function coverage. ## coverage.thresholds Options for coverage thresholds. If a threshold is set to a positive number, it will be interpreted as the minimum percentage of coverage required. For example, setting the lines threshold to `90` means that 90% of lines must be covered. If a threshold is set to a negative number, it will be treated as the maximum number of uncovered items allowed. For example, setting the lines threshold to `-10` means that no more than 10 lines may be uncovered. ```ts { coverage: { thresholds: { // Requires 90% function coverage functions: 90, // Require that no more than 10 lines are uncovered lines: -10, } } } ``` ### coverage.thresholds.lines - **Type:** `number` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.lines=` Global threshold for lines. ### coverage.thresholds.functions - **Type:** `number` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.functions=` Global threshold for functions. ### coverage.thresholds.branches - **Type:** `number` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.branches=` Global threshold for branches. ### coverage.thresholds.statements - **Type:** `number` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.statements=` Global threshold for statements. ### coverage.thresholds.perFile - **Type:** `boolean | { 100?: boolean, lines?: number, functions?: number, branches?: number, statements?: number }` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.perFile`, `--coverage.thresholds.perFile=false` When `true`, each file is checked against the top-level thresholds instead of the project-wide aggregate. When set to an object, both are checked: the aggregate against the top-level thresholds, and every file against these per-file minimums. ```ts { coverage: { thresholds: { lines: 80, functions: 80, branches: 80, statements: 80, perFile: { lines: 50, functions: 50, branches: 50, statements: 50, }, } } } ``` `{ 100: true }` is also accepted inside the object as a shortcut for setting all four metrics to `100`: ```ts { coverage: { thresholds: { lines: 80, perFile: { 100: true, }, } } } ``` `perFile` can also be set on an individual [glob-pattern threshold](/config/coverage#coverage-thresholds-glob-pattern). Glob patterns do **not** inherit the top-level `perFile`; set it on each glob explicitly. ```ts { coverage: { thresholds: { perFile: true, lines: 80, 'src/utils/**': { lines: 90, perFile: true, }, } } } ``` ### coverage.thresholds.autoUpdate - **Type:** `boolean | function` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.autoUpdate=` Update all threshold values `lines`, `functions`, `branches` and `statements` to configuration file when current coverage is better than the configured thresholds. This option helps to maintain thresholds when coverage is improved. You can also pass a function for formatting the updated threshold values. The function receives the new threshold as the first argument and the previous threshold as the second: ```ts { coverage: { thresholds: { // Log the change and update without decimals autoUpdate: (newThreshold, previousThreshold) => { console.log(`Updated threshold from ${previousThreshold} to ${newThreshold}`) return Math.floor(newThreshold) }, // 95.85 -> 95 functions: 95, } } } ``` ### coverage.thresholds.100 - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.thresholds.100`, `--coverage.thresholds.100=false` Sets global thresholds to 100. Shortcut for `--coverage.thresholds.lines 100 --coverage.thresholds.functions 100 --coverage.thresholds.branches 100 --coverage.thresholds.statements 100`. ### coverage.thresholds[glob-pattern] - **Type:** `{ statements?: number, functions?: number, branches?: number, lines?: number, perFile?: boolean | object }` - **Default:** `undefined` - **Available for providers:** `'v8' | 'istanbul'` Sets thresholds for files matching the glob pattern. Each glob pattern can set its own `perFile` (`boolean | object`), checked exactly like the top-level `perFile` but scoped to the matched files. Glob patterns do not inherit the top-level `perFile` — set it per glob. ::: tip NOTE Vitest counts all files, including those covered by glob-patterns, into the global coverage thresholds. This is different from Jest behavior. ::: ```ts { coverage: { thresholds: { // Thresholds for all files functions: 95, branches: 70, // Thresholds for matching glob pattern 'src/utils/**.ts': { statements: 95, functions: 90, branches: 85, lines: 80, // each matching file must individually hit the thresholds above perFile: true, }, // Files matching this pattern will only have lines thresholds set. // Global thresholds are not inherited. '**/math.ts': { lines: 100, } } } } ``` ### coverage.thresholds[glob-pattern].100 - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8' | 'istanbul'` Sets thresholds to 100 for files matching the glob pattern. ```ts { coverage: { thresholds: { // Thresholds for all files functions: 95, branches: 70, // Thresholds for matching glob pattern 'src/utils/**.ts': { 100: true }, '**/math.ts': { 100: true } } } } ``` ## coverage.ignoreClassMethods - **Type:** `string[]` - **Default:** `[]` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.ignoreClassMethods=` Set to array of class method names to ignore for coverage. See [istanbul documentation](https://github.com/istanbuljs/nyc#ignoring-methods) for more information. ## coverage.watermarks - **Type:** ```ts { statements?: [number, number], functions?: [number, number], branches?: [number, number], lines?: [number, number] } ``` - **Default:** ```ts { statements: [50, 80], functions: [50, 80], branches: [50, 80], lines: [50, 80] } ``` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.watermarks.statements=50,80`, `--coverage.watermarks.branches=50,80` Watermarks for statements, lines, branches and functions. See [istanbul documentation](https://github.com/istanbuljs/nyc#high-and-low-watermarks) for more information. ## coverage.processingConcurrency - **Type:** `boolean` - **Default:** `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)` - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.processingConcurrency=` Concurrency limit used when processing the coverage results. ## coverage.instrumenter 4.1.5 {#coverage-instrumenter} - **Type:** `(options: InstrumenterOptions) => CoverageInstrumenter` - **Available for providers:** `'istanbul'` Factory for a custom instrumenter to use in place of the default `@vitest/istanbul-lib-instrument`. Vitest calls the factory once during initialization and reuses the returned instrumenter for every file. The rest of the Istanbul pipeline (collection, merging, reporting) is unchanged. The factory receives an `InstrumenterOptions` object with Vitest's runtime coverage settings, and must return an object implementing the `CoverageInstrumenter` interface. Both types are exported from `vitest/node`. ```ts interface InstrumenterOptions { coverageVariable: string coverageGlobalScope: string coverageGlobalScopeFunc: boolean ignoreClassMethods: string[] } interface CoverageInstrumenter { instrumentSync: (code: string, filename: string, inputSourceMap?: any) => string lastSourceMap: () => any lastFileCoverage: () => any } ``` ```ts import { defineConfig } from 'vitest/config' import { createInstrumenter } from '@vitest/some-custom-instrumenter' export default defineConfig({ test: { coverage: { provider: 'istanbul', instrumenter: options => createInstrumenter(options), } } }) ``` ## coverage.customProviderModule - **Type:** `string` - **Available for providers:** `'custom'` - **CLI:** `--coverage.customProviderModule=` Specifies the module name or path for the custom coverage provider module. See [Guide - Custom Coverage Provider](/guide/coverage#custom-coverage-provider) for more information. ## coverage.htmlDir - **Type:** `string` - **Default:** Automatically inferred from `html`, `html-spa`, or `lcov` coverage reporters - **CLI:** `--coverage.htmlDir=` Directory of HTML coverage output to be served in [Vitest UI](/guide/ui) and [HTML reporter](/guide/reporters.html#html-reporter). This is automatically configured when using builtin coverage reporters that produce HTML output (`html`, `html-spa`, and `lcov`). Use this option to override with a custom coverage reporting location when using custom coverage reporters. Note that setting this option does not change where coverage HTML report is generated. Configure the `coverage.reporter` option to change the directory instead. ## coverage.changed - **Type:** `boolean | string` - **Default:** `false` (inherits from `test.changed`) - **Available for providers:** `'v8' | 'istanbul'` - **CLI:** `--coverage.changed`, `--coverage.changed=` Collect coverage only for files changed since a specified commit or branch. When set to `true`, it uses staged and unstaged changes. ## coverage.autoAttachSubprocess 5.0.0 {#coverage-autoattachsubprocess} - **Type:** `boolean` - **Default:** `false` - **Available for providers:** `'v8'` - **CLI:** `--coverage.autoAttachSubprocess` Track coverage of the `node:child_process` and `node:worker_threads` spawned during test run. Note that this option has some performance overhead as its using [`NODE_V8_COVERAGE`](https://nodejs.org/api/cli.html#node-v8-coveragedir) internally. This triggers Node to write lots of unnecessary files on file system.