vitest/no-large-snapshots

Disallow snapshots that are longer than a set number of lines

Nobody reads a snapshot that's several hundred lines long in a review. When it changes, someone updates it without looking, and then the test passes no matter what the code does. A short snapshot, or an assertion on the few values that matter, still tells you something when it fails.

The rule counts the lines in the first argument of toMatchInlineSnapshot and toThrowErrorMatchingInlineSnapshot. The limit is 50 lines. A snapshot that comes after a property matcher isn't counted.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"vitest/no-large-snapshots" = "error" # or "warn"

Every option, set to its default. The ones that are commented out are unset by default.

bunfig.toml
[lint.rules]
"vitest/no-large-snapshots" = ["error", {
  # inlineMaxSize = <value>,
  maxSize = 50,
  allowedSnapshots = {},
}]

Examples#

These examples set inlineMaxSize to 3 to stay short.

example.tswith { "inlineMaxSize": 3 }1 problem
import { expect, test } from "vitest";

test("loads the user", () => {
  expect(loadUser(1)).toMatchInlineSnapshot(`
    {
      "email": "ada@example.com",
      "id": 1,
      "name": "Ada",
    }
  `);
});
example.tswith { "inlineMaxSize": 3 }No problems
import { expect, test } from "vitest";

test("loads the user", () => {
  const user = loadUser(1);
  expect(user.name).toBe("Ada");
  expect(user.email).toMatchInlineSnapshot(`"ada@example.com"`);
});

Options#

OptionDefaultWhat it does
inlineMaxSizethe value of maxSizeThe most lines an inline snapshot can have.
maxSize50The most lines a snapshot in a .snap file can have.
allowedSnapshots{}Snapshots in .snap files that can have any length. Each key is the absolute path to a .snap file, and its value is a list of snapshot names or regular expressions.

bun lint skips .snap files unless you ask for them:

bun lint --ext .snap

With an ESLint config, list .snap files under files instead. An oxlint config never lints them. If .snap files aren't linted, maxSize only sets the default for inlineMaxSize, and allowedSnapshots has no effect.

.oxlintrc.json
{
  "plugins": ["vitest"],
  "rules": {
    "vitest/no-large-snapshots": ["error", { "inlineMaxSize": 20 }]
  }
}

Without inlineMaxSize, maxSize applies to inline snapshots:

example.tswith { "maxSize": 3 }1 problem
import { expect, test } from "vitest";

test("lists the roles", () => {
  expect(roles()).toMatchInlineSnapshot(`
    [
      "admin",
      "editor",
      "viewer",
    ]
  `);
});