Skip to main content

Overview

Every CI run of a Vitest suite starts from zero and runs every test, even when a change only touches a few files. The @useblacksmith/vitest plugin uses dependency tracking to run only the tests affected since the last successful run. It is one plugin in vitest.config.ts, with no workflow change.
The plugin is in early beta. Options and the cache format may change between releases.

How it works

Each run records the modules and files every test depends on, through import, require, and fs. The next run compares the checkout against that record and runs only the tests that reach a changed file. A test the last successful run did not cover always runs, and a lockfile change runs everything. On Blacksmith runners, Blacksmith transparently stores this record from run to run, with no extra workflow steps.

Install the plugin

The plugin requires Vitest 5.1 or newer.
vitest run now runs the affected selection. --shard=i/n works as before, and a file stays in its shard as others are added or removed.

Vite+

Vite+ runs Vitest under vp test, so the plugin is loaded from the shared vite.config.ts. It requires vite-plus 1.5.0 or newer, the first release that ships Vitest 5.1.

Running locally

The same selection applies locally: a run reruns what changed on disk since the last successful run, committed or not. To run every test locally and select only in CI:

Evaluate before relying on it

shadow runs every test and logs what the selection would have run, and which failing test files it would have skipped. It needs a cached record, so it reports only on Blacksmith runners. Run it for a few days to see the savings and confirm the selection misses nothing before turning it on.

Options

Limitations

Only dependencies in the test process are tracked. Files read from a child process, from globalSetup, or from outside Node are not; declare them with the dependencies option. A custom sequencer that moves tests between shards across runs reruns each moved test once. Under Turborepo’s strict environment mode, vitest cannot see ACTIONS_RESULTS_URL, so the record is not shared between runs. Add it to the task’s passThroughEnv in turbo.json.

Verify the selection

The plugin logs every decision with a [blacksmith] prefix in the job output: whether a record was restored, how many files changed since the last successful run, and how many test files run as a result. The first run on a repository has no record and runs everything; compare the test step’s duration across later runs. A run after a change to one source file restores the record, runs only the test file that depends on it, and saves a new record:
When no change affects any test, Vitest prints No changed files found, exiting with code 0 and the step passes.