testing-library/react-testing-library
π Simple and complete React DOM testing utilities that encourage good testing practices.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained β safe to depend on.
Has a license, tests, and CI β clean foundation to fork and modify.
Documented and popular β useful reference codebase to read through.
No critical CVEs, sane security posture β runnable as-is.
- βLast commit 5w ago
- β25+ active contributors
- βMIT licensed
- βCI configured
- βTests present
- β Concentrated ownership β top contributor handles 52% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the βHealthyβ badge
Paste into your README β live-updates from the latest cached analysis.
[](https://repopilot.app/r/testing-library/react-testing-library)Paste at the top of your README.md β renders inline like a shields.io badge.
βΈPreview social card (1200Γ630)
This card auto-renders when someone shares https://repopilot.app/r/testing-library/react-testing-library on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: testing-library/react-testing-library
Generated by RepoPilot Β· 2026-05-06 Β· Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale β STOP and ask the user to regenerate it before proceeding. - Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/testing-library/react-testing-library shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO β Healthy across the board
- Last commit 5w ago
- 25+ active contributors
- MIT licensed
- CI configured
- Tests present
- β Concentrated ownership β top contributor handles 52% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live testing-library/react-testing-library
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale β regenerate it at
repopilot.app/r/testing-library/react-testing-library.
What it runs against: a local clone of testing-library/react-testing-library β the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in testing-library/react-testing-library | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit β€ 64 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of testing-library/react-testing-library. If you don't
# have one yet, run these first:
#
# git clone https://github.com/testing-library/react-testing-library.git
# cd react-testing-library
#
# Then paste this script. Every check is read-only β no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of testing-library/react-testing-library and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "testing-library/react-testing-library(\\.git)?\\b" \\
&& ok "origin remote is testing-library/react-testing-library" \\
|| miss "origin remote is not testing-library/react-testing-library (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift β was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/index.js" \\
&& ok "src/index.js" \\
|| miss "missing critical file: src/index.js"
test -f "src/pure.js" \\
&& ok "src/pure.js" \\
|| miss "missing critical file: src/pure.js"
test -f "src/config.js" \\
&& ok "src/config.js" \\
|| miss "missing critical file: src/config.js"
test -f "src/act-compat.js" \\
&& ok "src/act-compat.js" \\
|| miss "missing critical file: src/act-compat.js"
test -f "src/fire-event.js" \\
&& ok "src/fire-event.js" \\
|| miss "missing critical file: src/fire-event.js"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 64 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~34d)"
else
miss "last commit was $days_since_last days ago β artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) β safe to trust"
else
echo "artifact has $fail stale claim(s) β regenerate at https://repopilot.app/r/testing-library/react-testing-library"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
A software project. See architecture tab.
Who it's for
Developers.
Maturity & risk
See activity metrics.
Standard open source risks apply.
Active areas of work
Check recent commits.
Get running
Check README for instructions.
Map of the codebase
src/index.jsβ Main entry point exporting render, cleanup, and other core testing utilities; every contributor must understand the public API surface.src/pure.jsβ Pure implementation of render without auto-cleanup; essential for understanding the library's two-mode architecture and setup/teardown logic.src/config.jsβ Global configuration management for testIdAttribute and cleanup behavior; required reading for customization and plugin development.src/act-compat.jsβ React act() wrapper and compatibility layer; critical for understanding async testing patterns and React version handling.src/fire-event.jsβ Event firing abstraction layer; core for understanding how user interactions are simulated in tests.package.jsonβ Dependency tree and build scripts; determines React peer version, testing-library/dom dependency, and build targets.types/index.d.tsβ TypeScript type definitions for the public API; critical for TypeScript users and IDE autocompletion understanding.
Components & responsibilities
- render(component, options) (React, ReactDOM, @testing-library/dom) β Main entry point: mounts React component into jsdom container, returns query helpers and utilities
- Failure mode: Component fails to mount (React error), act() warnings if state updates not wrapped, memory leak if cleanup is skipped
- cleanup() β Unmounts all rendered components and clears the DOM
How to make changes
Add a new testing utility or wrapper
- Implement the utility function in src/index.js or create a new src/my-utility.js file (
src/index.js) - Add TypeScript type definitions in types/index.d.ts, following the pattern of existing render/renderHook exports (
types/index.d.ts) - Add unit tests in src/tests/my-utility.js covering happy path, edge cases, and error scenarios (
src/__tests__/render.js) - Export the new utility from src/index.js so it's included in the public API (
src/index.js)
Modify React rendering or cleanup behavior
- Update the render implementation in src/pure.js, which is the core undecorated function (
src/pure.js) - For auto-cleanup behavior, update src/index.js which wraps the pure version with afterEach hooks (
src/index.js) - Add or update tests in src/tests/auto-cleanup.js or src/tests/render.js (
src/__tests__/auto-cleanup.js) - Update TypeScript definitions in types/index.d.ts to reflect signature changes (
types/index.d.ts) - Test against multiple React versions by running jest with different peer dependencies (
package.json)
Update global library configuration options
- Add new configuration option to the config object in src/config.js with getter/setter patterns (
src/config.js) - Use the config value in relevant files (e.g., testIdAttribute in queries, cleanup in src/index.js) (
src/index.js) - Add TypeScript interface updates in types/index.d.ts (configure function signature) (
types/index.d.ts) - Add test in src/tests/config.js validating the configuration behavior (
src/__tests__/config.js)
Why these technologies
- React Testing Library (wrapper around @testing-library/dom) β Encourages testing user behavior and accessibility rather than implementation details; single unified query API across web testing
- React.act() compatibility layer β Ensures React state updates and effects complete before assertions; handles different React versions (16.8+) without exposing complexity
- Jest for test execution β Default test runner with built-in afterEach hook support for automatic cleanup; snapshot testing for render output
- TypeScript definitions β Provides IDE autocompletion and compile-time safety; enables discovery of all available query methods
Trade-offs already made
-
Two entry points: auto-cleanup (src/index.js) vs manual cleanup (src/pure.js)
- Why: Different projects need different patterns; some use Jest (auto-cleanup via afterEach), others use Vitest or manual test frameworks
- Consequence: Adds complexityβmust maintain two code paths, but offers flexibility for all testing setups
-
Re-exports @testing-library/dom queries rather than reimplementing them
- Why: Avoids duplication and ensures consistency with vanilla DOM testing; leverages well-maintained shared code
- Consequence: Introduces tight coupling to @testing-library/dom API, but reduces maintenance burden
-
Wraps React.act() with version detection and error suppression
- Why: React 16.8+ changed act() behavior; library must work seamlessly across versions without user awareness
- Consequence: Adds a wrapper layer that hides complexity, but may suppress legitimate warnings if not handled carefully
-
Provides both fireEvent and userEvent (via re-export from @testing-library/user-event)
- Why: fireEvent is fast but synthetic; userEvent is slower but closer to real browser behaviorβusers choose trade-off
- Consequence: Increases API surface and can confuse beginners about which to use; requires documentation
Non-goals (don't propose these)
- Does not handle E2E testing; React Testing Library is unit/integration focused (no browser control, no real network mocking)
- Does not provide visual regression testing; tests interact with DOM queries, not pixel comparisons
- Does not replace Storybook or pattern libraries; orthogonal tools for documenting components
- Does not handle styling or CSS-in-JS assertions; focuses on behavior and accessibility
- Does not support server-side rendering (SSR) in jsdom; assumes client-side React in a browser-like DOM environment
Traps & gotchas
Standard debugging applies.
Architecture
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive TypeScript tests for pure.d.ts exports
The repo has a pure.d.ts file for the pure export but the types/test.tsx file doesn't appear to have dedicated tests for the pure bundle's TypeScript definitions. This ensures type safety for users importing from @testing-library/react/pure.
- [ ] Review types/pure.d.ts to identify all exported types and functions
- [ ] Expand types/test.tsx or create types/pure.test.tsx with test cases for pure bundle imports
- [ ] Add tests verifying the pure bundle doesn't export cleanup utilities (only rendering utilities)
- [ ] Run typecheck script to validate: npm run typecheck
- [ ] Add a test case that ensures users get proper TS errors when trying to import cleanup from pure
Add integration tests for dont-cleanup-after-each.js configuration
The repo ships dont-cleanup-after-each.js as a public API (listed in package.json files), but src/tests/auto-cleanup.js and src/tests/auto-cleanup-skip.js don't thoroughly test the configuration mechanism for this file. This should verify it works in different test environments.
- [ ] Review src/tests/auto-cleanup-skip.js to understand current testing approach
- [ ] Add a new test file src/tests/dont-cleanup-config.js that imports dont-cleanup-after-each.js
- [ ] Test that config.js respects the cleanup setting when dont-cleanup-after-each.js is required
- [ ] Add tests verifying this works with different Jest configurations (jest.config.js variations)
- [ ] Document the expected behavior in a test case comment for future maintainers
Add error boundary and act() warning tests for edge cases
The src/tests/act.js and src/tests/error-handlers.js files exist but based on the fire-event.js implementation and act-compat.js, there are likely edge cases with async act() calls and error handling that need coverage. This improves reliability for users dealing with warnings.
- [ ] Review src/act-compat.js for async handling and error scenarios
- [ ] Review src/fire-event.js for act() usage patterns with async events
- [ ] Add tests in src/tests/act.js for: async act() with errors, nested act() calls, and promise rejections
- [ ] Add tests verifying proper console.error warnings are emitted for act() violations
- [ ] Add a test case for act() behavior when component has an error boundary
- [ ] Run npm test to ensure all tests pass and coverage is maintained
Good first issues
Check the issue tracker.
Top contributors
- @eps1lon β 52 commits
- @allcontributors[bot] β 13 commits
- @MatanBobi β 12 commits
- @MichaelDeBoey β 2 commits
- @Goldyvaiiii β 1 commits
Recent commits
be9d81dβ docs: fix typos in comments and types (#1446) (Goldyvaiiii)f32bd1bβ fix: Update 'onCaughtError' type inference in 'RenderOptions' to work with React v19 (#1438) (aicest)a2d37ffβ fix: Switch to trusted publishing (#1437) (eps1lon)cd6a175β chore: fix action permissions (#1436) (MatanBobi)22b8c28β chore: fix release (#1435) (MatanBobi)d996673β chore: new release workflow (#1434) (MatanBobi)205ce17β chore: fix typo in jest.config.js (#1427) (black5box)aba5740β [test] Fix tests forreact@experimental(#1424) (eps1lon)590bc18β [test] Fixnpm run typecheck(#1423) (eps1lon)1c931a6β chore(deps): usenpm-run-all2(#1411) (MichaelDeBoey)
Security observations
The React Testing Library codebase has a good security posture overall. This is a testing utility library with minimal external attack surface. Key observations: (1) Truncated peerDependencies field needs completion for proper validation; (2) Several dependencies could be updated to newer versions for better security coverage; (3) No hardcoded credentials, secrets, or sensitive configuration files detected in the provided structure; (4) No obvious injection vulnerabilities based on file structure analysis - this is a testing library, not a server application; (5) No Docker infrastructure issues identified. The main recommendations are to complete the package.json configuration and keep dependencies up-to-date.
- Low Β· Incomplete peerDependencies Declaration β
package.json - peerDependencies field. The package.json file shows a truncated peerDependencies field that appears to be cut off at '@testing-library/d'. This incomplete dependency declaration could lead to unexpected behavior or missing peer dependency validation. Fix: Ensure the peerDependencies field is complete and properly formatted. Verify that all required peer dependencies (@testing-library/dom, @testing-library/react, react, react-dom, etc.) are fully declared with appropriate version constraints. - Low Β· Use of Deprecated Chalk Version β
package.json - devDependencies. The package uses chalk@^4.1.2, which is an older major version. While not a direct security vulnerability, newer versions may contain bug fixes and security improvements. Chalk v5+ is the current stable version. Fix: Consider upgrading chalk to the latest major version (v5.x) to benefit from newer features and security improvements. Test compatibility before upgrading. - Low Β· Babel Runtime Dependency Without Lock File Context β
package.json - dependencies. The package depends on @babel/runtime@^7.12.5, which is a relatively old version (from 2020). While @babel/runtime provides sandboxed utilities, using outdated versions may miss security updates and performance improvements. Fix: Update @babel/runtime to a more recent version (7.20.0 or later). Verify compatibility with your supported Node versions (>=18) and test thoroughly.
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues β current backlog
- Recent PRs β what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals β see the live page for receipts. Re-run on a new commit to refresh.