DOM Testing Library

Simple, framework-agnostic DOM query utilities that test your UI the way real users interact with it.

Library
npm
v10.4.2
3,338 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 48
Community 72
Maturity 60
Momentum 40

Technical Analysis

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

DOM Testing Library is the framework-agnostic engine behind the entire Testing Library family (React Testing Library, Vue Testing Library, Angular Testing Library, and more). Rather than reaching into component internals or instance state, it queries plain DOM nodes the same way a person would find them: by visible text, label, placeholder, role, or test id. Its guiding principle — “the more your tests resemble the way your software is used, the more confidence they can give you” — pushes teams away from brittle, implementation-coupled tests and toward tests that survive refactors.

At its core sit a small set of composable primitives: getByX/queryByX/findByX/getAllByX query variants generated from shared helpers in query-helpers.ts, an accessibility-first getByRole implementation that mirrors how screen readers see the page, and an async waitFor/waitForElementToBeRemoved pair built on MutationObserver (with a Jest fake-timers-aware code path) for asserting on DOM changes without arbitrary sleeps. A configure() API lets consumers override the test-id attribute, default query behavior, and error formatting, which is exactly the extension point React/Vue/Svelte Testing Library build on top of.

With roughly 70 million weekly npm downloads for this package alone and adoption across nearly every major JS UI framework’s own testing tooling, it has become the de facto standard for behavior-driven, user-centric UI testing in the JavaScript ecosystem.

What You Get

  • A full family of getBy/queryBy/findBy/getAllBy/queryAllBy/findAllBy query variants for text, label text, placeholder text, alt text, title, display value, test id, and ARIA role
  • An accessibility-aware getByRole query that computes implicit ARIA roles and accessible names the way assistive technology does
  • Async waitFor and waitForElementToBeRemoved helpers built on MutationObserver, with correct behavior under both real and Jest fake timers
  • A global configure() API for setting the test-id attribute, default query behavior (e.g. hidden, exact, custom text normalizers), and custom error formatting
  • Built-in query suggestions that nudge you toward higher-priority, more accessible queries (e.g. suggesting getByRole over getByTestId)
  • A prettyDOM/logRoles debugging toolkit that prints a readable DOM snapshot or the accessibility tree straight into failed-test output

Common Use Cases

  • Writing framework-agnostic tests for vanilla JS or web-component UIs without pulling in a component-testing wrapper
  • Serving as the underlying query/assertion engine for React Testing Library, Vue Testing Library, Angular Testing Library, and similar framework adapters
  • Asserting that async UI updates (loading spinners disappearing, content appearing after a fetch) have completed, via waitFor/waitForElementToBeRemoved instead of manual timeouts
  • Auditing and testing accessibility by querying elements the same way assistive technology perceives them, via getByRole and getRoles/logRoles
  • Migrating test suites away from snapshot- or selector-based testing toward behavior-driven tests that don’t break on internal refactors

Under The Hood

Architecture

The library is organized as a small, composable core rather than a monolith: src/query-helpers.ts exposes buildQueries, a factory that takes a single queryAllBy* implementation and mechanically derives the queryBy/getBy/getAllBy/findBy/findAllBy variants (the findBy* variants are produced by wrapping the getter in waitFor from src/wait-for.js), so every query type in src/queries/ (text, role, label-text, placeholder-text, alt-text, title, display-value, test-id) is generated from one shared implementation instead of being hand-duplicated six times over. get-queries-for-element.js binds the whole query set to a given container to power both the top-level screen object and the within() helper, so scoping queries to a subtree is structurally the same operation as querying the whole document. Global behavior (test-id attribute name, error formatting, async timeouts, suggestion opt-in) flows through a single mutable config object in config.ts, read via getConfig() everywhere queries or waitFor need a default — the one clear central dependency in an otherwise flat, function-composition-heavy design.

Tech Stack

The package is written in a mix of plain JavaScript and TypeScript (.ts files hold the newer, more heavily-typed modules like query-helpers.ts, config.ts, and matches.ts), built via kcd-scripts (a shared Babel/Rollup/Jest toolchain wrapper from the same maintainer ecosystem as this project) into CJS, ESM, and UMD bundles declared under main/module/umd:main in package.json. Runtime dependencies are deliberately minimal — aria-query and dom-accessibility-api power the ARIA-role and accessible-name computation behind getByRole, pretty-format and picocolors drive the colorized DOM snapshots used in error messages, and lz-string compresses cached data for repeated snapshot diffing. Type declarations are hand-maintained under types/ rather than machine-generated, giving consumers curated public-facing types independent of internal implementation types.

Code Quality

The project has an extensive Jest test suite under src/__tests__ (dozens of spec files, one roughly per source module, e.g. role.js, wait-for.js, queries.find.js, suggestions.js) plus a parallel src/__node_tests__ suite and split tests/jest.config.dom.js / jest.config.node.js projects to exercise both jsdom and plain Node environments — a testing posture unusually thorough even by this ecosystem’s standards. Linting and formatting are enforced via the shared kcd-scripts ESLint/Prettier config with project-specific rule overrides in package.json, and CI (.github/workflows/validate.yml) runs validation on every push. Error handling favors explicit, purpose-built TestingLibraryElementError instances carrying a pretty-printed DOM snapshot rather than swallowing failures, and naming is consistent throughout (queryAllBy* → queryBy* → getBy* → findBy* derivations follow the same pattern in every query family).

What Makes It Unique

What differentiates this library from ad hoc DOM query helpers is that its queries are deliberately biased toward accessibility semantics rather than raw selectors: getByRole reconstructs the ARIA role and accessible name the way a screen reader would, and the built-in suggestion system actively warns when a test uses a lower-priority query (like a test id) where a higher-priority, more accessible one (like a role or label) would have matched — encoding an opinionated testing philosophy directly into the tool’s runtime behavior rather than leaving it to a style guide. Combined with its role as the shared foundation reused verbatim by nearly every major framework’s own testing-library package, this makes it less a single tool and more a de facto specification for user-centric UI testing across the JS ecosystem.

Used by 87 apps in this directory

TypeScript
85%
MIT

LibreChat

AI Assistants · Developer Tools

46,236

Unite every major AI model in one self-hosted chat platform with agents, code execution, MCP tools, and enterprise authentication.

View details
93
Repo Health
81
Technical
62
Dependency
Built with
TypeScript 85%
JavaScript 14%
Updated 6 days ago
JavaScript
42%
Other

LimeSurvey

Forms Surveys

3,778

The world's most flexible open-source survey platform with 900+ templates, conditional logic, 80+ languages, and full GDPR compliance for any scale.

View details
86
Repo Health
62
Technical
62
Dependency
Built with
JavaScript 42%
PHP 36%
CSS 12%
Updated 6 days ago
Python
84%
MIT

LiteLLM

AI Development · Developer Tools

61,933

Open source AI gateway and Python SDK that gives you one OpenAI-compatible interface to call 100+ LLM providers, with built-in routing, cost tracking, guardrails, and virtual keys.

View details
93
Repo Health
81
Technical
69
Dependency
Built with
Python 84%
TypeScript 11%
Updated 6 days ago
JavaScript
55%
Other

Lokus

Knowledge Management · Note Taking

829

Local-first note-taking with graph view, canvas & AI plugins—your Markdown files, zero telemetry, blazing-fast Rust performance.

View details
75
Repo Health
75
Technical
64
Dependency
Built with
JavaScript 55%
HTML 21%
Rust 12%
Updated 2 months ago
Ruby
59%
AGPL 3.0

Mastodon

Social Media

50,441

Run your own federated social network on the open ActivityPub standard with no ads, no algorithms, and no corporate control over your community.

View details
95
Repo Health
81
Technical
70
Dependency
Built with
Ruby 59%
TypeScript 24%
Updated 6 days ago
TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

29,041

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 6 days ago
TypeScript
51%
Other

Mattermost

Collaboration · Devops · Team Chat

39,418

Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.

View details
96
Repo Health
87
Technical
65
Dependency
Built with
TypeScript 51%
Go 40%
Updated 6 days ago
TypeScript
88%
Apache 2.0

Medplum

Authentication · Databases · Developer Tools

2,760

An open-source, FHIR-native healthcare platform that gives developers a compliant backend, authentication, a React component library, and serverless bots to build clinical applications in weeks instead of years.

View details
93
Repo Health
90
Technical
71
Dependency
Built with
TypeScript 88%
Updated 6 days ago
TypeScript
87%
MIT

medusa

Ecommerce

36,897

The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.

View details
94
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 87%
JavaScript 12%
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