Safeguard
Security

eslint-plugin-jest-dom: What It Secures and What It Does Not

eslint-plugin-jest-dom enforces better jest-dom assertions, but as a dev dependency it also lives in your supply chain. Here is where its real security value and its real risk both sit.

Yukti Singhal
Platform Engineer
4 min read

eslint-plugin-jest-dom is a lint plugin from the Testing Library team that pushes you toward correct, semantic jest-dom assertions, and while it does not touch production code, it is still an installed dependency with a place in your supply chain that deserves the same auditing as any other package. Its direct security contribution is indirect but real: better test hygiene catches more bugs before they ship, including some that have security consequences.

Teams often lump it in with eslint-plugin-jest and treat "eslint jest" tooling as one thing. They are related but distinct, and understanding the split matters both for correctness and for knowing what you have actually installed.

What the plugin enforces

eslint-plugin-jest-dom targets the custom matchers provided by @testing-library/jest-dom. Instead of asserting on implementation details, it nudges you to assertions that describe user-visible state. A typical rule rewrites a brittle check into a semantic one:

// flagged by the plugin
expect(button.disabled).toBe(true);

// preferred
expect(button).toBeDisabled();

The security-adjacent value is that semantic assertions fail loudly when behavior changes. A test that checks toBeDisabled() will catch a regression that re-enables a control which should stay locked — for example a submit button that is supposed to stay disabled until validation passes. Weak assertions let that kind of regression through, and some of those regressions are the ones that matter for authorization or input handling.

How it relates to eslint-plugin-jest and eslint jest tooling

These are three overlapping things people conflate:

  • eslint-plugin-jest lints your Jest test structure — no disabled tests, no focused tests left in, correct use of expect.
  • eslint-plugin-jest-dom lints your DOM assertions specifically, the jest-dom matchers.
  • The broader "eslint jest" setup is usually both of those plus the base ESLint config and a shared preset.

They are complementary. Many projects install eslint-plugin-jest and eslint-plugin-jest-dom together, often alongside eslint-plugin-testing-library. Each is a separate entry in your package.json and a separate line in your lockfile, which means each is a separate thing to keep patched.

Dev dependencies are still supply chain

The mistake teams make is assuming that because a package only runs at lint time, it does not matter for security. It does. Anything in node_modules executes on developer machines and in CI, which are high-value targets. A compromised ESLint plugin runs with the same privileges as your build — it can read environment variables, exfiltrate CI secrets, or tamper with output. Historically, several npm supply chain incidents rode in through exactly these kinds of "harmless" build and lint tools.

Audit your dev dependencies with the same seriousness as production ones:

npm audit
npm ls eslint-plugin-jest-dom eslint-plugin-jest eslint

An SCA scan that includes dev dependencies — many teams accidentally scope scans to production only — will surface advisories in the lint tooling too. Configure your scanner to cover both trees. If you want a deeper primer on why build-time packages matter, our Academy walks through the CI attack surface in detail.

Pinning and provenance

Pin the plugin version and let Renovate or Dependabot propose upgrades so you review each bump rather than floating on ^. When installing, confirm you have the canonical eslint-plugin-jest-dom (published under the Testing Library org) and not a look-alike. Check the linked repository, the maintainer, and the download count. The eslint-plugin-jest name has a large weekly download volume, which makes typosquats around it attractive, so verify the exact string before you add it.

Wiring it into a flat config

Modern ESLint uses flat config. Register the plugin explicitly so you know precisely what is loaded:

import jestDom from 'eslint-plugin-jest-dom';

export default [
  {
    files: ['**/*.test.{js,jsx,ts,tsx}'],
    ...jestDom.configs['flat/recommended'],
  },
];

Scoping the plugin to test files keeps it out of your production lint pass and makes the dependency's blast radius easy to reason about.

FAQ

Does eslint-plugin-jest-dom run in production?

No. It runs only at lint time on developer machines and in CI. It does not ship in your production bundle. It is still an installed dependency, so it belongs in your dependency audit.

What is the difference between eslint-plugin-jest and eslint-plugin-jest-dom?

eslint-plugin-jest lints Jest test structure and usage, while eslint-plugin-jest-dom lints the jest-dom DOM assertion matchers specifically. They are complementary and are commonly installed together.

Should I include dev dependencies in my security scan?

Yes. Lint and build tooling runs with access to CI secrets and developer environments, which have been the entry point for real npm supply chain attacks. Configure your SCA scan to cover dev dependencies, not just production.

How do I avoid installing a typosquatted plugin?

Confirm the exact package name, check that it is published by the Testing Library organization, review the linked GitHub repository, and compare the weekly download count against what you expect before installing.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.