# testing-library/react-testing-library — codebase unpack

> Canonical page: https://codevetter.com/unpack/react-testing-library

This is a deterministic Repo Unpack scan of testing-library/react-testing-library — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: 20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800 (2026-08-27)
- Last upstream commit: fix: Avoid act() re-entrant when dispatching events (#1468)
- Generated by codevetter 1.15.0 on 2026-10-02
- 65 files scanned · 383 KB

Source inspection; upstream code and tests were not executed.

## Languages

- JavaScript: 31 files
- Markdown: 12 files
- JSON: 4 files
- TypeScript: 4 files
- YAML: 3 files

## Repository structure

- src/ — 23 files
- .github/ — 7 files
- other/ — 5 files
- types/ — 4 files
- tests/ — 4 files
- .codesandbox/ — 1 files

Probable source entrypoint: `src/index.js` (inferred from the tree, not upstream docs)

## Source layout — src/

- src/__mocks__/ — 1 file
- src/__tests__/ — 17 files
- src/act-compat.js — 1 file
- src/config.js — 1 file
- src/fire-event.js — 1 file
- src/index.js — 1 file
- src/pure.js — 1 file

## Package

- package.json: @testing-library/react v0.0.0-semantically-released — 14 declared dependencies

## Structural health signals

Average score 8.9/10 across 31 files; 0 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- 20ce75f2907c (2026-08-28) fix: Avoid act() re-entrant when dispatching events (#1468)
- be9d81d91314 (2026-04-02) docs: fix typos in comments and types (#1446)
- f32bd1b033d5 (2026-01-19) fix: Update 'onCaughtError' type inference in 'RenderOptions' to work with React v19 (#1438)
- a2d37ffa09d8 (2025-12-15) fix: Switch to trusted publishing (#1437)
- cd6a175a2806 (2025-12-13) chore: fix action permissions (#1436)

## Overview

React Testing Library is a developer testing library that renders React components into a DOM and exposes queries and interaction helpers shaped around observable user behavior. At commit 20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800, its small JavaScript runtime adapts React 18/19 roots, act scheduling, hydration, hook rendering, and cleanup while delegating DOM queries to @testing-library/dom. It ships npm entrypoints and handwritten TypeScript declarations; this brief is based on read-only inspection of runtime files, tests, documentation, configuration, and workflows.

## System map

The runtime is a library loaded into a consumer's test process and DOM environment. React owns rendering, DOM Testing Library owns query machinery, and this repository supplies lifecycle and scheduling adapters. Distribution and release are described by package scripts and GitHub workflows.
- The package advertises dist/index.js as main, an ESM bundle as module, types/index.d.ts as declarations, and Node >=18. — [package.json#L2-L10](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L2-L10)
- src/index.js adds runner lifecycle hooks and then re-exports src/pure.js; the published pure.js shim instead requires dist/pure. — [src/index.js#L9-L41](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L9-L41) [pure.js#L1-L2](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/pure.js#L1-L2)
- src/pure.js is the orchestration module: it imports React, both ReactDOM APIs, DOM query utilities, act compatibility, event adaptation, and configuration. — [src/pure.js#L1-L14](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L1-L14) [src/pure.js#L369-L371](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L369-L371)
- Root adapters provide a common hydrate/render/unmount interface over ReactDOMClient and legacy ReactDOM methods. — [src/pure.js#L102-L163](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L102-L163)
- Lifecycle storage consists of module-local mountedContainers and mountedRootEntries; cleanup clears both after unmounting. — [src/pure.js#L79-L88](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L79-L88) [src/pure.js#L317-L328](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L317-L328)
- React and ReactDOM 18 or 19 and DOM Testing Library 10 are peer integrations; @babel/runtime is the declared production dependency. — [package.json#L47-L49](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L47-L49) [package.json#L65-L79](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L65-L79)
- Build runs three parallel kcd-scripts targets; test, lint, validate, and typecheck are package scripts, with typecheck invoking tsc against the root config. — [package.json#L11-L24](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L11-L24) [tsconfig.json#L33-L44](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tsconfig.json#L33-L44)
- Release builds npm artifacts after validation and invokes semantic-release 25 only for pushes in the upstream repository; the package includes dist, shims, and declaration files. — [package.json#L26-L32](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L26-L32) [.github/workflows/release.yml#L81-L115](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L81-L115)

## Feature catalog

The user-facing surface is an API for test authors. It supports rendering, updating, hydration, hooks, interactions, diagnostics, and test isolation. DOM Testing Library exports broaden that surface without duplicating query implementations here.
- render accepts React UI and returns container, baseElement, bound queries, debug, rerender, unmount, and asFragment. — [src/pure.js#L197-L235](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L197-L235) [types/index.d.ts#L28-L47](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L28-L47)
- Custom container and baseElement options control mounting and query scope; without either, render creates a div under document.body. — [src/pure.js#L238-L275](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L238-L275) [src/__tests__/multi-base.js#L18-L38](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/multi-base.js#L18-L38)
- hydrate attaches React to existing markup, while legacyRoot selects older rendering APIs only when ReactDOM.render exists. — [src/pure.js#L114-L129](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L114-L129) [src/pure.js#L253-L265](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L253-L265) [src/__tests__/render.js#L179-L201](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L179-L201)
- wrapper supplies a surrounding component, and reactStrictMode can be configured globally or overridden per render. — [src/pure.js#L90-L100](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L90-L100) [types/index.d.ts#L152-L163](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L152-L163)
- renderHook exposes a stable result ref, rerender, and unmount, with initialProps passed to the hook callback. — [src/pure.js#L330-L366](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L330-L366) [types/index.d.ts#L184-L204](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L184-L204)
- fireEvent forwards DOM event helpers and adds React-specific enter/leave, selection, and focus/blur event sequences; act is also publicly exported. — [src/fire-event.js#L7-L67](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/fire-event.js#L7-L67) [src/pure.js#L369-L371](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L369-L371)
- Consumers receive DOM Testing Library exports, including screen and asynchronous query utilities used in the integration tests. — [src/pure.js#L369-L371](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L369-L371) [src/__tests__/end-to-end.js#L1-L7](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L1-L7) [src/__tests__/end-to-end.js#L55-L74](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L55-L74)
- cleanup is public and normally registered automatically; consumers can choose the pure entrypoint or load dont-cleanup-after-each.js to control teardown themselves. — [src/index.js#L4-L23](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L4-L23) [dont-cleanup-after-each.js#L1-L1](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/dont-cleanup-after-each.js#L1-L1) [pure.js#L1-L2](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/pure.js#L1-L2) [src/pure.js#L371-L371](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L371-L371)

## Data flow

React nodes and render options enter the root orchestration layer, then become DOM content and query-bound results. Configuration and scheduling state are shared within the loaded modules and test global. Hook output and snapshots are transient outputs rather than durable persistence.
- render rejects a supplied onUncaughtError and unsupported legacyRoot before defaulting baseElement or allocating a container. — [src/pure.js#L238-L275](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L238-L275)
- A new container selects a root factory and records the root in both tracking structures; a known container retrieves its existing root by scanning mountedRootEntries. — [src/pure.js#L277-L304](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L277-L304)
- UI is first wrapped in the optional wrapper component, then optionally enclosed in StrictMode, before rendering or hydration inside act. — [src/pure.js#L90-L100](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L90-L100) [src/pure.js#L177-L195](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L177-L195)
- onCaughtError and onRecoverableError flow into createRoot or hydrateRoot at root creation; they are not supplied anew when an existing root is reused. — [src/pure.js#L114-L129](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L114-L129) [src/pure.js#L279-L303](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L279-L303)
- Queries bind to baseElement, whereas asFragment serializes container.innerHTML into a DocumentFragment and debug formats its selected element through prettyDOM. — [src/pure.js#L197-L205](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L197-L205) [src/pure.js#L222-L235](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L222-L235)
- configure evaluates functional deltas against merged configuration, forwards non-reactStrictMode fields to DOM Testing Library, and assigns reactStrictMode in RTL's local config. — [src/config.js#L10-L31](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/config.js#L10-L31)
- renderHook computes pendingResult during TestComponent rendering, publishes it to result.current in useEffect, and passes new rerender arguments as renderCallbackProps. — [src/pure.js#L343-L366](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L343-L366)
- cleanup unmounts roots inside act, removes only containers directly under document.body, and clears in-memory tracking; custom parent elements remain outside that removal boundary. — [src/pure.js#L317-L328](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L317-L328) [src/__tests__/multi-base.js#L5-L16](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/multi-base.js#L5-L16)

## Behavior traces

The inspected flows cover import setup, component lifecycle, hydration, events, async queries, and hooks. Each trace follows runtime functions and relevant test usage rather than assuming behavior from filenames. These walks were read from source and were not executed.
- Startup: pure-module evaluation installs DOM timer/async/event wrappers; index.js then checks RTL_SKIP_AUTO_CLEANUP, registers afterEach or teardown, and registers beforeAll/afterAll act-environment management when both hooks exist. — [src/pure.js#L32-L77](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L32-L77) [src/index.js#L9-L38](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L9-L38)
- Initial render: render validates options → defaults to document.body → appends a div → createConcurrentRoot calls createRoot → tracking is populated → renderRoot calls root.render inside act → query helpers are returned. — [src/pure.js#L125-L144](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L125-L144) [src/pure.js#L253-L294](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L253-L294) [src/pure.js#L306-L314](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L306-L314) [src/pure.js#L177-L235](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L177-L235)
- Update and teardown: result.rerender calls renderRoot with the captured root, wrapper, and scope; result.unmount calls root.unmount in act; cleanup later walks registered roots and clears their tracking. — [src/pure.js#L206-L220](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L206-L220) [src/pure.js#L317-L328](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L317-L328) [src/__tests__/rerender.js#L20-L26](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/rerender.js#L20-L26)
- Hydration: render with hydrate:true creates a concurrent root through act(hydrateRoot); renderRoot subsequently calls the adapter's no-op hydrate, and rerender later uses root.render. The hydration test then clicks the existing button and asserts updated text. — [src/pure.js#L114-L144](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L114-L144) [src/pure.js#L177-L195](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L177-L195) [src/pure.js#L211-L218](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L211-L218) [src/__tests__/render.js#L189-L200](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L189-L200)
- Interaction: fireEvent.click forwards to the DOM helper; the configured eventWrapper runs its callback inside act, but nested wrapper invocations execute directly. The nesting regression dispatches input from an effect and checks both updates and act warnings. — [src/fire-event.js#L7-L11](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/fire-event.js#L7-L11) [src/pure.js#L62-L75](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L62-L75) [src/__tests__/event-wrapper-nesting.js#L6-L25](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/event-wrapper-nesting.js#L6-L25) [src/__tests__/event-wrapper-nesting.js#L41-L51](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/event-wrapper-nesting.js#L41-L51)
- Async query: a fixture effect schedules a promise or timer update → the test awaits waitFor/findBy → asyncWrapper disables the act flag, awaits its callback, drains microtasks via setTimeout(0), advances detected Jest fake timers, and restores the prior flag in finally. — [src/__tests__/end-to-end.js#L19-L42](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L19-L42) [src/__tests__/end-to-end.js#L55-L74](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L55-L74) [src/pure.js#L39-L60](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L39-L60)
- Hook flow: renderHook extracts initialProps → render mounts TestComponent → renderCallback computes output → useEffect writes result.current → returned rerender calls baseRerender with new props, while unmount is inherited from render. — [src/pure.js#L330-L366](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L330-L366) [src/__tests__/renderHook.js#L10-L50](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/renderHook.js#L10-L50)
- Explicit act: withGlobalActEnvironment saves the prior flag and enables it; synchronous callbacks restore immediately, object thenables restore on resolution/rejection, and synchronous exceptions restore before rethrow. — [src/act-compat.js#L36-L79](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/act-compat.js#L36-L79) [src/__tests__/act.js#L47-L69](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/act.js#L47-L69)

## Testing signals

Tests and CI were inspected, not executed; no passing result or measured coverage is asserted. Jest suites in src/__tests__ exercise DOM behavior, scheduling, cleanup, hooks, and React-version branches, while types/test.tsx supplies declaration checks. The inspected inventory is bounded, and several tests or configuration branches explicitly limit what can be concluded.
- Jest configuration extends kcd-scripts/config, and tests/setup-env.js installs jest-dom assertions, console-call enforcement, TextEncoder, and a worker_threads MessageChannel. — [jest.config.js#L1-L19](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/jest.config.js#L1-L19) [tests/setup-env.js#L1-L9](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tests/setup-env.js#L1-L9)
- Rendering tests assert portals, fragment snapshots, wrapper composition, StrictMode effects, repeated-container rendering, hydration interactivity, and version-gated legacy behavior. — [src/__tests__/render.js#L34-L90](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L34-L90) [src/__tests__/render.js#L93-L160](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L93-L160) [src/__tests__/render.js#L163-L219](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L163-L219) [src/__tests__/render.js#L222-L263](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L222-L263)
- Cleanup suites test automatic cleanup and its skip switch, effect teardown, detached containers, non-flushing of microtasks, and preservation of missing-act warnings. — [src/__tests__/auto-cleanup.js#L4-L13](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/auto-cleanup.js#L4-L13) [src/__tests__/auto-cleanup-skip.js#L3-L18](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/auto-cleanup-skip.js#L3-L18) [src/__tests__/cleanup.js#L25-L42](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/cleanup.js#L25-L42) [src/__tests__/cleanup.js#L58-L125](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/cleanup.js#L58-L125)
- Event tests generate React-handler and native-listener cases from an event table; a separate regression asserts nested eventWrapper behavior and absence of act warnings. — [src/__tests__/events.js#L147-L205](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/events.js#L147-L205) [src/__tests__/event-wrapper-nesting.js#L41-L54](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/event-wrapper-nesting.js#L41-L54)
- Async integration tests exercise waitForElementToBeRemoved, waitFor, and findBy across real, legacy fake, and modern fake timers, including long promise chains; their loaders simulate data rather than contacting a server. — [src/__tests__/end-to-end.js#L4-L27](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L4-L27) [src/__tests__/end-to-end.js#L55-L74](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L55-L74) [src/__tests__/end-to-end.js#L78-L124](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L78-L124) [src/__tests__/end-to-end.js#L139-L162](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L139-L162)
- Hook tests assert committed output, rerender props, providers, and version-gated legacy roots; renderHook's recoverable-error test accepts the option but contains a TODO instead of triggering recovery. — [src/__tests__/renderHook.js#L10-L68](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/renderHook.js#L10-L68) [src/__tests__/renderHook.js#L70-L113](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/renderHook.js#L70-L113) [src/__tests__/error-handlers.js#L170-L183](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/error-handlers.js#L170-L183)
- types/test.tsx checks render/query/config/hook usage and container inference; root typecheck includes types with strict and exactOptionalPropertyTypes enabled, but onCaughtError's cross-version fixture uses @ts-ignore. — [types/test.tsx#L5-L49](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/test.tsx#L5-L49) [types/test.tsx#L215-L263](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/test.tsx#L215-L263) [types/test.tsx#L266-L289](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/test.tsx#L266-L289) [tsconfig.json#L21-L44](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tsconfig.json#L21-L44)
- PR CI spans Node 18/24 and React 18.x/latest/canary/experimental, permits non-latest failures, and uploads coverage. Jest relaxes per-job core thresholds while Codecov specifies a 100% project target for selected flags. — [.github/workflows/validate.yml#L14-L22](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/validate.yml#L14-L22) [.github/workflows/validate.yml#L53-L61](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/validate.yml#L53-L61) [jest.config.js#L4-L17](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/jest.config.js#L4-L17) [codecov.yml#L1-L18](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/codecov.yml#L1-L18)

## Risk map

The main source-observed risks concern shared state, lifecycle boundaries, compatibility, and validation strength. Security-sensitive authority appears in release automation; the inspected core runtime operates on the test DOM and callbacks rather than implementing authentication or transport. These observations and labeled hypotheses are not confirmed vulnerabilities or whole-repository absence claims.
- Even the pure implementation changes shared DOM Testing Library configuration at import time and writes IS_REACT_ACT_ENVIRONMENT during operations; selecting pure only avoids index.js lifecycle registration. — [src/pure.js#L32-L77](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L32-L77) [src/act-compat.js#L28-L39](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/act-compat.js#L28-L39) [src/index.js#L9-L38](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L9-L38)
- RTL_SKIP_AUTO_CLEANUP is tested by truthiness rather than equality with 'true', and the same guard disables both cleanup registration and suite-level act-environment hooks. — [src/index.js#L9-L38](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L9-L38) [src/__tests__/auto-cleanup-skip.js#L3-L18](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/auto-cleanup-skip.js#L3-L18)
- configure assigns reactStrictMode even when a delta omits it, replacing the previous value with undefined; the inspected config suite does not assert retention after a DOM-only delta. — [src/config.js#L24-L31](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/config.js#L24-L31) [src/__tests__/config.js#L19-L66](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/config.js#L19-L66)
- The Set and array must remain synchronized; result.unmount does not deregister its root, and a later render on that container selects the stored root. This is a lifecycle hotspot, not a demonstrated failure in this inspection. — [src/pure.js#L79-L88](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L79-L88) [src/pure.js#L206-L210](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L206-L210) [src/pure.js#L279-L303](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L279-L303)
- Async scheduling depends on Jest-specific timer markers and a zero-delay timer to drain microtasks; global flag restoration for asynchronous act is tied to consuming its returned thenable. — [src/pure.js#L16-L27](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L16-L27) [src/pure.js#L39-L60](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L39-L60) [src/act-compat.js#L54-L69](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/act-compat.js#L54-L69)
- debug sends formatted DOM to console.log, while asFragment reparses container.innerHTML without a sanitization step. Hypothesis: sensitive fixture content can enter logs or snapshots; these helpers are not a content-security boundary. (inferred) — [src/pure.js#L200-L205](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L200-L205) [src/pure.js#L222-L232](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L222-L232) [src/__tests__/render.js#L78-L90](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L78-L90)
- README authentication and localStorage code is an example application, while inspected async test loaders return synthetic promises. Treating those as shipped authentication, persistence, or real-network coverage would misstate the library boundary. — [README.md#L224-L259](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/README.md#L224-L259) [src/__tests__/end-to-end.js#L19-L27](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L19-L27) [src/__tests__/end-to-end.js#L93-L97](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/end-to-end.js#L93-L97) [src/pure.js#L369-L371](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L369-L371)
- Release automation grants OIDC and repository write permissions, consumes workflow secret references, and installs without a lockfile; non-latest React validation jobs allow failure. These are consequential release boundaries, with no credential values read or exploit established. — [.github/workflows/release.yml#L25-L32](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L25-L32) [.github/workflows/release.yml#L73-L85](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L73-L85) [.github/workflows/release.yml#L95-L117](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L95-L117)

## Extension points

Consumer extension primarily happens through render options and configuration rather than a plugin registry. The root adapters and event forwarding also provide internal seams for compatibility work. Public additions need coordinated runtime exports, declarations, and behavioral tests.
- RenderOptions.queries accepts a custom query set, and renderRoot binds it through getQueriesForElement; custom sets replace defaults unless the caller merges them. — [types/index.d.ts#L147-L151](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L147-L151) [src/pure.js#L234-L235](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L234-L235)
- RenderResult maps each supplied query key to BoundFunction, preserving custom-query typing through the generic render overload. — [types/index.d.ts#L28-L47](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L28-L47) [types/index.d.ts#L171-L182](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L171-L182)
- wrapper is the documented seam for reusable render helpers that install providers; renderHook passes it through the same render pipeline. — [types/index.d.ts#L152-L158](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L152-L158) [src/pure.js#L355-L358](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L355-L358) [src/__tests__/renderHook.js#L53-L68](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/renderHook.js#L53-L68)
- configure accepts object or functional deltas and forwards DOM options, supporting changes such as testIdAttribute alongside RTL strict mode. — [src/config.js#L17-L31](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/config.js#L17-L31) [src/__tests__/config.js#L19-L64](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/config.js#L19-L64)
- createConcurrentRoot and createLegacyRoot are internal factories with the same lifecycle methods; render chooses between them via legacyRoot. — [src/pure.js#L132-L163](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L132-L163) [src/pure.js#L279-L288](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L279-L288)
- fireEvent copies every enumerable DOM helper at module load, then overrides selected helpers; new React event adaptations belong beside those explicit sequences. — [src/fire-event.js#L7-L35](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/fire-event.js#L7-L35) [src/fire-event.js#L38-L67](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/fire-event.js#L38-L67)
- onCaughtError and onRecoverableError are root-creation callback seams, with onCaughtError typed conditionally against installed ReactDOM RootOptions; onUncaughtError is deliberately excluded. — [types/index.d.ts#L122-L145](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L122-L145) [src/pure.js#L114-L129](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L114-L129) [src/pure.js#L253-L257](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L253-L257)
- The pure import lets alternative runners own cleanup scheduling while retaining the public API; its declaration forwarding chain ends at the same types/index.d.ts surface. — [src/index.js#L4-L8](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L4-L8) [pure.js#L1-L2](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/pure.js#L1-L2) [pure.d.ts#L1-L1](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/pure.d.ts#L1-L1) [types/pure.d.ts#L1-L1](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/pure.d.ts#L1-L1)

## Contributor handoff

Begin edits at the runtime/type boundary and read the focused behavioral suite before changing contracts. Existing scripts and workflow definitions describe intended validation, but tests and CI were inspected, not executed during this assignment. The investigation is bounded and supplies neither passing results nor exhaustive security or coverage conclusions.
- For lifecycle work, first read index.js, pure.js, and act-compat.js together: runner registration, root ownership, and React's global act flag cross module boundaries. — [src/index.js#L9-L38](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/index.js#L9-L38) [src/pure.js#L277-L328](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/pure.js#L277-L328) [src/act-compat.js#L36-L79](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/act-compat.js#L36-L79)
- Keep public API edits paired with types/index.d.ts and types/test.tsx; CONTRIBUTING identifies handwritten declarations as the API update location. — [CONTRIBUTING.md#L35-L43](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/CONTRIBUTING.md#L35-L43) [types/index.d.ts#L171-L182](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/index.d.ts#L171-L182) [types/test.tsx#L215-L263](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/types/test.tsx#L215-L263)
- For an authorized implementation, start with the relevant src/__tests__ suite through npm test, then use typecheck or validate as needed; those commands were only inspected here. — [package.json#L21-L24](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L21-L24) [src/__tests__/render.js#L12-L32](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L12-L32) [src/__tests__/renderHook.js#L10-L22](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/renderHook.js#L10-L22)
- Preserve React 18/19 branches and version-gated assertions; a successful latest-only run would not establish legacy-root compatibility. — [package.json#L65-L70](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L65-L70) [src/__tests__/render.js#L6-L10](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L6-L10) [src/__tests__/render.js#L222-L263](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/render.js#L222-L263)
- Tests changing global configuration capture and restore it; tests mocking console must respect the harness's unexpected-call and teardown checks. — [src/__tests__/config.js#L3-L17](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/src/__tests__/config.js#L3-L17) [tests/failOnUnexpectedConsoleCalls.js#L58-L93](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tests/failOnUnexpectedConsoleCalls.js#L58-L93) [tests/failOnUnexpectedConsoleCalls.js#L124-L129](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tests/failOnUnexpectedConsoleCalls.js#L124-L129)
- Use actual scripts as authority over older documentation: CONTRIBUTING mentions dtslint, while package.json's explicit typecheck invokes tsc and the root config includes types without emitting output. — [CONTRIBUTING.md#L35-L43](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/CONTRIBUTING.md#L35-L43) [package.json#L23-L24](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L23-L24) [tsconfig.json#L41-L44](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/tsconfig.json#L41-L44)
- Inspect package-manager context before installing: package.json declares Yarn 1.22.22, while contribution setup and CI use npm, and CI explicitly disables lockfile use. — [package.json#L116-L116](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/package.json#L116-L116) [CONTRIBUTING.md#L8-L12](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/CONTRIBUTING.md#L8-L12) [.github/workflows/validate.yml#L33-L36](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/validate.yml#L33-L36)
- Treat release automation as a separate authority boundary: configured branch pushes can trigger publication, and maintainer documentation warns that BREAKING CHANGE commit text drives major releases. — [.github/workflows/release.yml#L2-L13](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L2-L13) [.github/workflows/release.yml#L81-L115](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/.github/workflows/release.yml#L81-L115) [other/MAINTAINING.md#L49-L63](https://github.com/testing-library/react-testing-library/blob/20ce75f2907ca0e5c5a8ae595c0e9a4e368c7800/other/MAINTAINING.md#L49-L63)

Source repository: https://github.com/testing-library/react-testing-library
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/react-testing-library.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
