Snapshot Testing in Vitest: How to Capture, Update, and Verify Stable Output
Learn how Vitest’s built‑in snapshot testing captures output, updates snapshots with –u, and avoids pitfalls like dynamic data and snapshot bloat.
21 Jul 2026, 22:32 UTC

Snapshot Testing in Vitest: The Quick Takeaway
Vitest’s toMatchSnapshot() matcher lets you record the stringified value of an assertion the first time a test runs. Subsequent runs compare the current output to the stored snapshot. If they differ, Vitest prints a line‑by‑line diff, and the test fails. Updating the snapshot is as simple as adding the -u (or --update-snapshots) flag.
How Vitest Stores Snapshots
When a test file example.test.ts calls toMatchSnapshot(), Vitest creates a __snapshots__ directory next to the test file. Inside, a file named example.test.ts.snap holds the snapshot. The file is a plain text representation of the value, usually JSON or a rendered component string.
Creating Your First Snapshot Test
// src/__tests__/greeting.test.ts
import { describe, it, expect } from 'vitest';
function greet(name: string) {
return `Hello, ${name}!`;
}
describe('greet', () => {
it('returns a greeting', () => {
const result = greet('World');
expect(result).toMatchSnapshot();
});
});
Run vitest in the project root. On the first run, Vitest will create __snapshots__/greeting.test.ts.snap containing:
"Hello, World!"
Future runs compare the function’s output to that string.
Updating Snapshots Safely
If you intentionally change greet to return Hello, Vitest!, the test will fail. To accept the new output, rerun with the update flag:
vitest -u
Vitest rewrites the snapshot file with the new value and prints a diff showing the change. Always commit the updated snapshot to source control; otherwise, CI pipelines that run tests on a clean checkout will fail.
Masking Dynamic Data
Snapshot tests are brittle when the output contains timestamps, random IDs, or environment‑specific data. Two common strategies:
- Transform before snapshotting: Pass a sanitized version of the data to
toMatchSnapshot().const data = { id: 123, timestamp: Date.now(), message: 'ok' }; const safe = { ...data, timestamp: '2026-10-16T00:00:00Z' }; expect(safe).toMatchSnapshot(); - Use
expect.stringContaining()for partial matches: When only part of a string matters.expect(result).toMatchSnapshot(); // If the string contains a dynamic UUID, replace it: const cleaned = result.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g, 'UUID'); expect(cleaned).toMatchSnapshot();
For more complex structures, Vitest allows custom snapshot serializers that can strip or format fields before snapshotting.
Common Pitfalls and Limits
- Snapshot bloat: Large objects (e.g., full API responses) create huge snapshot files. Consider snapshotting only the relevant slice of the data.
- Uncontrolled dynamic data: Forgetting to stub timestamps or random values leads to frequent failures. Always sanitize before snapshotting.
- Missing commits: Updated snapshots that aren’t committed break CI. Add a pre‑commit check or CI step to flag missing snapshots.
- Over‑reliance on snapshots: Snapshots detect changes but don’t assert correctness. Use them alongside explicit assertions for critical logic.
Verifying Snapshot Integrity
- Run
vitestto generate or verify snapshots. - When a test fails, review the console diff. Vitest shows the old and new lines with
+and-markers. - Open the corresponding
__snapshots__/*.snapfile to confirm the stored value matches the expected output. - If the change is intentional, run
vitest -uand commit the new snapshot.
Quick Reference Table
| Command | Purpose |
|---|---|
vitest | Run tests, compare snapshots |
vitest -u | Update all snapshots |
vitest --no-snapshot-update | Run tests without updating snapshots |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.