Vitest Cheatsheet

Snapshots

Use this Vitest reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Basic Snapshot

import { expect, it } from 'vitest'

it('renders correctly', () => {
  const result = renderComponent()
  expect(result).toMatchSnapshot()
})

On first run, Vitest writes a .snap file. On subsequent runs it compares against it.

Inline Snapshots

it('formats output', () => {
  expect(formatUser({ name: 'Alice', age: 30 })).toMatchInlineSnapshot(`
    "Alice (30)"
  `)
})

The snapshot string is written into the test file itself on first run. Useful for small, reviewable values.

Updating Snapshots

vitest -u
vitest run --update

-u / --update is Vitest's flag (--update-snapshots is Playwright's, not Vitest's). Or use the UI's "Update snapshot" button.

Snapshot Files

Stored in __snapshots__/<testfile>.snap next to the test file:

src/
  components/
    Button.test.tsx
    __snapshots__/
      Button.test.tsx.snap

Snapshot File Format

// Vitest Snapshot v1, https://vitest.dev/guide/snapshot

exports[`renders correctly 1`] = `
{
  "tag": "button",
  "text": "Click me",
}
`;

Custom Snapshot Serializers

import { expect } from 'vitest'

expect.addSnapshotSerializer({
  test(val) {
    return val && typeof val === 'object' && 'html' in val
  },
  print(val) {
    return (val as { html: string }).html
  },
})

it('serializes html', () => {
  expect({ html: '<p>Hello</p>' }).toMatchSnapshot()
  // snapshot: `<p>Hello</p>`
})

toMatchSnapshot with Property Matchers

Use asymmetric matchers to ignore dynamic values (timestamps, IDs):

it('ignores dynamic fields', () => {
  expect(createUser()).toMatchSnapshot({
    id: expect.any(String),
    createdAt: expect.any(Date),
    name: 'Alice', // exact match for stable fields
  })
})

toThrowErrorMatchingSnapshot

it('error message snapshot', () => {
  expect(() => parseConfig('bad input')).toThrowErrorMatchingSnapshot()
})

// Inline version:
expect(() => parseConfig('')).toThrowErrorMatchingInlineSnapshot(`
  "Config cannot be empty"
`)

React Component Snapshots (with @testing-library/react)

import { render } from '@testing-library/react'
import { expect, it } from 'vitest'
import { Button } from './Button'

it('button snapshot', () => {
  const { container } = render(<Button label="Click me" />)
  expect(container.firstChild).toMatchSnapshot()
})

Snapshot Best Practices

  • Commit snapshots — they are the source of truth and must be reviewed in PRs.
  • Keep snapshots small — snapshot only the relevant output, not entire pages.
  • Review diffs carefully — accidental UI regressions look like expected changes.
  • Use inline snapshots for small, stable values (easier to review).
  • Prefer specific assertions over snapshots when the output is simple.
  • Regenerate intentionally — only run -u when you've verified the change is correct.

Clearing Obsolete Snapshots

Snapshot keys whose tests were renamed or deleted are reported as obsolete in the run summary. Remove them by re-running with the update flag:

vitest run -u

Custom Snapshot Directory

Use resolveSnapshotPath (there is no snapshotsDirName option in Vitest):

import path from 'node:path'

export default defineConfig({
  test: {
    resolveSnapshotPath: (testPath, snapExtension) =>
      path.join(path.dirname(testPath), '__snapshots__', path.basename(testPath) + snapExtension),
  },
})