Adetayo Akinsanya unkletayo.dev

Snapshot Testing Engine: AST Serializers, File Formatting, and Inline Snapshots

Deep dive into Vitest's snapshot engine, snapshot updates, and custom object serializers.

Adetayo Akinsanya (unkletayo) 2026-10-06

Part 8 in Series — Catch up on the previous article: Fake Timers, Microtasks, and Event Loop Time Manipulation (Part 7) before diving into this post.

Snapshot testing captures serialized representations of data structures or rendered DOM trees to prevent unintentional regression changes over time.

Vitest supports two snapshot formats:

  1. External Snapshots (toMatchSnapshot()): Written to __snapshots__/*.snap files alongside the test file.
  2. Inline Snapshots (toMatchInlineSnapshot()): Written directly into the test file source code using SWC/Babel AST transformation.
import { test, expect } from 'vitest';

test('matches external snapshot', () => {
  const user = { id: 101, role: 'admin', permissions: ['read', 'write'] };
  expect(user).toMatchSnapshot();
});

test('matches inline snapshot', () => {
  const user = { id: 102, role: 'member' };
  expect(user).toMatchInlineSnapshot(`
    {
      "id": 102,
      "role": "member",
    }
  `);
});

Custom Snapshot Serializers

When data contains dynamic fields (like generated timestamps or random UUIDs), standard snapshot matching fails. You can register custom snapshot serializers to sanitize output:

import { expect } from 'vitest';

expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    return `[User ID: ${val.id}]`;
  },
  test(val) {
    return val && typeof val === 'object' && 'id' in val && 'role' in val;
  },
});
Up Next in Series →

Part 9: Vitest Browser Mode: Executing Tests in Real Chromium, Firefox, and WebKit Engines

Continue to Part 9 →