jest-dom

Custom Jest matchers for asserting on the state of the DOM in your tests.

Library
npm
v7.0.1
4,600 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
64 /100 Good
Development Activity 36
Maintenance 56
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
80 /100 Excellent
Architecture 82
Code Quality 88
Innovation 60
Learning Curve 90

jest-dom is a companion library for Testing Library that adds a set of custom matchers to Jest (and Jest-compatible runners like Vitest) specifically for asserting on DOM nodes. Instead of manually inspecting element.textContent, element.getAttribute(...), or element.classList, you get declarative matchers such as toBeInTheDocument(), toHaveTextContent(), toHaveAttribute(), and toHaveClass() that read like the behavior they verify.

The library is deliberately narrow in scope: it does not render components or query the DOM itself (that’s the job of @testing-library/dom and its framework wrappers) — it only extends expect with matchers that operate on whatever DOM node your test already has a handle to. This keeps it usable across React, Vue, Angular, or plain DOM testing setups, and across both Jest and Vitest via a dedicated /vitest entry point.

Each matcher also produces test-failure output tailored to DOM assertions — printing the actual vs. expected text content, attribute value, or class list with contextual formatting — rather than Jest’s generic object-diff output, which is often unreadable for DOM nodes.

What You Get

  • Presence & visibility matchers - toBeInTheDocument(), toBeVisible(), and toBeEmptyDOMElement() for asserting whether and how an element renders.
  • Form-state matchers - toBeDisabled(), toBeEnabled(), toBeRequired(), toBeInvalid()/toBeValid(), toBeChecked(), and toHaveValue()/toHaveDisplayValue() for form and input assertions.
  • Content & attribute matchers - toHaveTextContent(), toHaveAttribute(), toHaveClass(), toHaveStyle(), and toContainHTML() for verifying rendered output.
  • Accessibility matchers - toHaveAccessibleName(), toHaveAccessibleDescription(), toHaveRole(), and toHaveErrorMessage() for asserting on the accessibility tree.
  • Dedicated entry points - separate /jest-globals and /vitest imports so the matchers register correctly whether you use Jest’s global expect or an explicit one.
  • DOM-aware failure output - custom error formatting that prints readable diffs of text content, attributes, and class lists instead of Jest’s default object serialization.

Common Use Cases

  • Asserting rendered React/Vue/Angular output - after rendering a component with @testing-library/react (or another framework adapter), asserting the resulting DOM node’s text, attributes, or visibility.
  • Form validation tests - checking that inputs are marked required, invalid, disabled, or hold a specific value after user interaction.
  • Accessibility regression tests - asserting accessible names, roles, and ARIA error messages stay correct as markup changes.
  • Migrating off enzyme or manual DOM assertions - replacing hand-rolled element.getAttribute(...) checks with declarative, self-describing matchers.
  • Cross-runner test suites - projects that run the same DOM assertions under both Jest and Vitest via the shared matcher set.

Under The Hood

Architecture jest-dom is structured as one small ES module per matcher (src/to-have-text-content.js, src/to-have-attribute.js, src/to-be-disabled.js, etc.), each exporting a single matcher function with the standard Jest matcher signature (received, ...args) => {pass, message}. src/matchers.js re-exports every matcher plus a generated set of toContainAnyBy*/toContainOneBy* query matchers, and src/index.js simply calls expect.extend(extensions) — the default side-effecting entry point most consumers import once in a test-setup file. Separate src/jest-globals.js and src/vitest.js entry points exist purely to register matchers against a runner-specific expect instead of relying on a Jest global, letting the same matcher implementations work unmodified across runners. Shared plumbing — type-checking, CSS parsing, message formatting — lives centrally in src/utils.js so every matcher throws and formats failures consistently.

Tech Stack The package is plain JavaScript (with a TypeScript-authored types/ tree for consumers) built with Rollup into CommonJS and ESM bundles, exposed through conditional exports map entries for require/import and per-entry-point type declarations. Runtime dependencies are intentionally minimal and focused: @adobe/css-tools for parsing CSS in toHaveStyle, aria-query for role/ARIA lookups, dom-accessibility-api for computing accessible names/descriptions per the WAI-ARIA spec, picocolors for terminal-safe diff coloring, and redent/css.escape for output formatting and selector escaping. @testing-library/dom and vitest are peer dependencies rather than bundled ones, keeping the library agnostic about which runner or query layer a consumer uses.

Code Quality The project has extensive test coverage: nearly every matcher in src/ has a same-named file under src/__tests__/, run through a dual Jest project config (tests/jest.config.dom and tests/jest.config.node) that exercises the matchers against both a real jsdom environment and a plain Node context. Error paths are explicit and typed via dedicated GenericTypeError, HtmlElementTypeError, NodeTypeError, and InvalidCSSError classes in utils.js rather than being swallowed, and every matcher validates its input node before proceeding. Linting and formatting are enforced through kcd-scripts (an opinionated ESLint/Prettier wrapper), and CI runs via GitHub Actions on each push, giving the project consistent, enforced conventions across a very large number of independently-authored matcher files.

API Design The library’s entire public surface is designed to read as natural-language test assertions — expect(element).toBeInTheDocument() versus manually checking document.body.contains(element) — and it deliberately mirrors Jest’s built-in matcher conventions (supporting .not, custom failure messages via this.utils.matcherHint) so it feels native rather than bolted on. Getting started requires a single import in a test-setup file with no configuration, and the conditional exports map means TypeScript users, Jest-globals users, and Vitest users each get a dedicated, correctly-typed entry point without extra setup steps.

Used by 166 apps in this directory

TypeScript
71%
Apache 2.0

open-design

Design Tools

100,256

Local-first, open-source Claude Design alternative that turns your existing coding agent CLI into a full agentic design studio — with 259+ skills, 142+ design systems, and sandboxed artifact delivery across web, desktop, and mobile surfaces.

View details
85
Repo Health
86
Technical
72
Dependency
Built with
TypeScript 71%
HTML 22%
Updated today
TypeScript
97%
GPL 3.0

OpenKnowledge

Code Editors · Knowledge Management · Note Taking

4,485

A beautiful, local-first markdown IDE that turns any git repo into a live collaborative workspace for humans and AI coding agents like Claude, Codex, and OpenCode.

View details
79
Repo Health
89
Technical
64
Dependency
Built with
TypeScript 97%
Updated today
TypeScript
56%
MIT

open-notebook

AI Assistants · Note Taking

40,014

A privacy-first, self-hosted AI research notebook with 18+ model providers, multi-speaker podcast generation, and full REST API—your open-source alternative to Google Notebook LM.

View details
89
Repo Health
84
Technical
71
Dependency
Built with
TypeScript 56%
Python 42%
Updated 5 days ago
Python
100%
Other

OpenBB

Analytics · Databases · Invoicing Finance

74,041

The AI Workspace for Finance: Connect Data, Run AI Agents, Build Analytics

View details
75
Repo Health
80
Technical
66
Dependency
Built with
Python 100%
Updated 1 weeks ago
Rust
60%
GPL 3.0

openfootmanager

Game Development

1,135

A free and open source football management simulation game built with Rust and Tauri, inspired by Football Manager.

View details
95
Repo Health
79
Technical
73
Dependency
Built with
Rust 60%
TypeScript 39%
Updated yesterday
TypeScript
93%
Other

OpenHands

AI Code Assistants · AI Development

90,429

The self-hosted developer control center for running AI coding agents — locally, in Docker, on VMs, or across cloud backends — with automation workflows for GitHub, Slack, and more.

View details
91
Repo Health
82
Technical
67
Dependency
Built with
TypeScript 93%
Updated today
Go
33%

OpenPanel

Devops · Hosting Control Panel

750

Docker-powered web hosting control panel that gives every user a fully isolated environment with dedicated web server, database, and networking — VPS-grade security on shared hardware.

View details
84
Repo Health
75
Technical
63
Dependency
Built with
Go 33%
HTML 31%
TypeScript 26%
Updated yesterday
Ruby
79%
GPL 3.0

OpenProject

Collaboration · Productivity · Project Management

16,369

The open source project management platform that unifies Gantt charts, agile boards, time tracking, and team collaboration under full self-hosted control.

View details
96
Repo Health
79
Technical
69
Dependency
Built with
Ruby 79%
TypeScript 13%
Updated today
TypeScript
93%
MIT

OpenReel Video

Video Editors

5,328

A browser-based, GPU-accelerated video editor with multi-track timelines, color grading, and 4K export — no uploads, no installs, no watermarks.

View details
72
Repo Health
80
Technical
75
Dependency
Built with
TypeScript 93%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers