All sites
Data API
Github Data API
Structured JSON data, on demand, with anti-bot bypass built in.
8endpointsRate Limit handled for you
Example (captured live) Open playground
github.com
ExampleJSON responseclick the page to trace a field
{
"full_name": "facebook/react",
"commits": [
{
"sha": "6c0e1047e392da04bccb36e84c04e1d1412901d6",
"message": "[Flight] Keep an element pending while a referenced row is resolving (#37542)
A row that is still parsing can hand its partially built value to
references that were registered on it during that parse.
`initializeModelChunk` fulfilled every such listener, on the assumption
that all of them are cyclic references back into the parsing row. Only
some are. A listener from a nested parse that is not part of a cycle
belongs to a handler that does not wait on the parsing row, so
fulfilling it early completes that handler with an object that still has
references outstanding.
When that handler owns an element, `initializeElement` runs on
incomplete props. In DEV the props are frozen, so the write that arrives
later throws `Cannot assign to read only property`, and
`rejectReference` escalates the error into the rows that wait on the
element, up to the root. Only the debug tree can produce this shape. The
RSC stream writes element props inline, while the debug channel outlines
a props object that an element shares with its own componentInfo into a
separate row, and that row can still wait on a client module.
`resolveBlockedCycle` already tells a cyclic reference from any other,
but it returned `null` for mid-parse listeners because `handler.chunk`
was assigned after the drain loop. This change assigns it before the
loop and classifies each listener. A reference whose handler is
transitively waiting on the parsing row is a genuine cycle and receives
the value now, because neither side can complete before the other. Every
other listener is queued back on the parsing row and fulfilled when that
row completes, like any reference into a blocked row.
A row whose own parse fails used to hand the partial value to its
mid-parse listeners before it threw. It now errors through
`triggerErrorOnChunk`, which rejects them the same way a reference into
any other errored row is rejected. The `if (handler.errored) throw`
after the loop is removed. It also caught a rejection during the loop,
which now reaches `triggerErrorOnChunk` on its own because
`handler.chunk` is set.
One behaviour changes beyond the reported bug. When
`initializeDebugChunk` errors a chunk before `parseModel` runs, the old
code set `INITIALIZED` over that status if the model had no pending
references, and left it `ERRORED` otherwise. The chunk now stays
`ERRORED` in both cases. That is what the `triggerErrorOnChunk` call in
`initializeDebugChunk` intends, and the TODO above the `parseModel` call
already notes that the chunk can be `ERRORED` there.
PR #37398 deferred `Object.freeze(element.props)` until the outstanding
references have resolved. That removes the exception but not the cause:
the element is still initialized on an incomplete object and is visible
through `_debugInfo` with a `null` placeholder until the late write
lands. With the early release fixed, the freeze needs no change.
**Alternatives Considered**
- Deferring every listener whose handler is not the parsing row's own
deadlocks `foo ↔ bar` in `can deduped outlined references inside
promises`. One side of a genuine cycle has to accept the partial object.
- Holding an element back while its props row is `BLOCKED` breaks
`should handle deduped props of re-used elements in fragments`, where
the row is blocked on an unrelated module and the props object itself is
complete.
- A per-object count of pending writes plus a reverse `dependents` edge
works, but adds a second dependency graph next to `deps` and
special-cases elements.
Fixes #37361
Closes #37398",
"author_name": "Hendrik Liebau",
"author_login": "unstubbable",
"date": "2026-09-08T11:31:40Z",
"url": "https://github.com/react/react/commit/6c0e1047e392da04bccb36e84c04e1d1412901d6",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "9b7a0d4029ee31f84446383b6530075f423e9904",
"message": "[DevTools] Document react-devtools-cdt-mcp for npm consumers (#37503)
## Summary
- Rewrite the package README so npm consumers can tell this is a
page-side library, not an MCP server.
- Document the chrome-devtools-mcp 1.3.0+ requirement, the experimental
third-party flag, and the corrected DOM-tool output.
Stacked on https://github.com/react/react/pull/37497
## Test plan
- [ ] Read the README as a first-time installer and confirm install,
import order, and MCP config are clear.
- [ ] Confirm `react_get_component_by_dom_element` no longer documents
`hooks`.",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-07T17:14:07Z",
"url": "https://github.com/react/react/commit/9b7a0d4029ee31f84446383b6530075f423e9904",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "f1f7ed2ac267a21dd2e3e67c4a606b9cf56e360b",
"message": "[rust-compiler] Preserve ref access location across phi joins (#37524)
Preserve the RefValue source location when joining mixed ref types so
validation errors point to the original ref access.
Before this change it used to show the incorrect location when using the
rust compiler.
```rust
2 | const ref = useRef(null);
3 | const x = cond ? ref : ref.current;
> 4 | return <Foo value={x} />;
| ^ Cannot access ref value during render
5 | }
6 |
```",
"author_name": "Jimmy Miller",
"author_login": "jimmyhmiller",
"date": "2026-09-04T20:59:38Z",
"url": "https://github.com/react/react/commit/f1f7ed2ac267a21dd2e3e67c4a606b9cf56e360b",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "8425b6915e8ebe2b12bf4bd42975bfccfa62fc5c",
"message": "[DevTools] Upgrade chrome-devtools-mcp to 1.8.0 in cdt-mcp e2e (#37497)
## Summary
- Upgrade the cdt-mcp e2e dependency from chrome-devtools-mcp 1.3.0 to
1.8.0.
- Pass `pageId` to page-scoped CLI tools, which 1.8.0 requires.
- Use a hex `sessionId` (`crypto.randomUUID()`). 1.8.0 rejects ids that
are not `/[a-fA-F0-9-]+/`.
Stacked on https://github.com/react/react/pull/37496
## Test plan
- [ ] `yarn --cwd packages/react-devtools-cdt-mcp test:e2e`",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-04T14:28:36Z",
"url": "https://github.com/react/react/commit/8425b6915e8ebe2b12bf4bd42975bfccfa62fc5c",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "d9f4e76bd6582ef86048fefcedda9d5b041ae62f",
"message": "[DevTools] Stop advertising hooks on react_get_component_by_dom_element (#37496)
## Summary
- `react_get_component_by_dom_element` returns the host node for a DOM
element, which never has hooks.
- Stop advertising `hooks?` in the tool description so agents do not
request a field that is never returned.
## Test plan
- [ ] `yarn test --build --project=devtools -r=experimental
DevToolsCdtMcp`",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-03T13:14:37Z",
"url": "https://github.com/react/react/commit/d9f4e76bd6582ef86048fefcedda9d5b041ae62f",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "18df76f617f9c8624585b8efde769d59e13308b2",
"message": "Update MAINTAINERS file (#37515)
Add myself to maintainers",
"author_name": "Pieter De Baets",
"author_login": "javache",
"date": "2026-09-03T13:05:51Z",
"url": "https://github.com/react/react/commit/18df76f617f9c8624585b8efde769d59e13308b2",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "0bbf02475c7b61a618551f1cf10c9bebf336f285",
"message": "[rust-compiler] Propagate block lowering errors (#37364)
Propagate errors from block lowering instead of continuing with
incomplete HIR.
This prevents the Rust compiler from emitting partial output when it
encounters unsupported syntax, including nested TypeScript `this`
parameters.
This landed earlier as #37232, which exposed an existing FBT diagnostic
ordering issue. Resolve local FBT bindings before checking whether an
`<fbt>` tag comes from a module import, so the compiler reports the
earlier, more useful Todo instead of a later invariant.
Run from the repository root:
- `yarn --cwd compiler workspace babel-plugin-react-compiler-rust test`
- `cargo test --manifest-path compiler/Cargo.toml -p
react_compiler_lowering`",
"author_name": "Will Binns-Smith",
"author_login": "wbinnssmith",
"date": "2026-09-02T20:28:52Z",
"url": "https://github.com/react/react/commit/0bbf02475c7b61a618551f1cf10c9bebf336f285",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "f4e439e1980f0748091f7d36c2005f0463197ed7",
"message": "[Fizz] Add `nonce` to rendered `import maps` (#37339)
Apply the render's script nonce to import maps emitted through the
`importMap` server rendering option. This keeps configured import maps
compatible with nonce-based Content Security Policies and uses the same
escaped nonce value as other render-managed scripts.",
"author_name": "Matthew Costabile",
"author_login": "mattcosta7",
"date": "2026-09-02T15:58:52Z",
"url": "https://github.com/react/react/commit/f4e439e1980f0748091f7d36c2005f0463197ed7",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "0d69e20fc03a7b2c750c3245d0ad19fb8e6f3b30",
"message": "[flags] Enable conditional `use()` warning in React's Canary builds (#37491)
The warning was previously only enabled for experimental builds
(`react@experimental`). This enables the warning for `react@canary` as
well.
Keep in mind that conditional `use()` is generally supported. This
warning only triggers if the condition is based on `promise.status` (or
`promise.value`). Let `use()` handle that status. React will not suspend
if the `promise.status` is already `'fulfilled'`.
More information can be found in the [`use()` docs under "Don’t skip
calling use based on whether a Promise is already
settled."](https://react.dev/reference/react/use#conditional-use).
We've tested this at Vercel on the latest version of SWR (which
previously had conditional `use()` calls) and found no false-positive
warnings or excessive warnings.",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-09-02T15:47:16Z",
"url": "https://github.com/react/react/commit/0d69e20fc03a7b2c750c3245d0ad19fb8e6f3b30",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "8f0043721ef508420ae3855d8e9f910b1fec1c85",
"message": "[Flight] Fix RangeError from exponential debug info growth (#37481)
The Flight Client copies the debug info of a referenced chunk into the
chunk that references it, so that the receiving chunk records what
blocked it. It copies the entries once per reference, and a referenced
chunk already carries the entries that it received itself. A response
that deduplicates the same object across a chain of rows therefore
multiplies the entries at every step. In development the array
eventually grows past what the engine can allocate for it, and the
client throws `RangeError: Invalid array length`.
The receiving chunk now takes each entry only once. The entries are
copied by reference and never cloned on this path, so a comparison by
identity is exact. The array becomes bounded by the number of distinct
entries in the response rather than by a chosen limit.
The bookkeeping costs one `Set` per chunk that receives debug info, in
development only. The set holds a reference to each entry rather than a
copy, so the entries stay shared and nothing about the debug info is
duplicated. A chunk receives entries only while it is blocked, so the
fix releases the set as soon as the chunk initializes. Debug info still
accumulates transitively, which this change does not alter.
This change also adds the `!reference.isDebug` guards that #37358
proposes for the element props branch and the default branch of
`fulfillReference`. #35795 introduced the rule that a reference resolved
during debug info resolution does not transfer, and it left those two
branches behind. The guards make that rule hold at every branch.
However, those branches reference debug chunks that carry no entries, so
the guards change no observed behaviour, and they do not fix the growth
in #37343, which comes from references in model chunks. #37343 also
reports the call in `getOutlinedModel` as unguarded, which it is not,
because #35795 already skips it there.
The rest of #37358 deduplicates the entries, which is the right
direction, but it scans the receiving array for every candidate, which
is quadratic in the size of the debug info. #37359 caps the array at a
constant instead, which stops the crash but keeps copying the duplicates
and drops debug info once a response passes the cap.
**Alternatives Considered**
- Tracking the referenced chunks rather than the entries would be
cheaper, because it would need one map entry per referenced chunk. It
would not be enough, because a chunk can reach the same entry through
two paths. A chunk can hold a client reference directly and also
reference a chunk that already received the debug info of that client
reference.
- Recording the last receiving chunk on each entry would be exact while
a chunk parses its model, where the transfers into it are consecutive.
It would break once transfers into different chunks interleave, and that
is the path the reported crash takes.
- Turning `_debugInfo` itself into a `Set` is not possible, because the
reconciler, Fizz, the Flight Server and DevTools read it by index and
depend on its order.
Fixes #37343
Closes #37358
Closes #37359
Co-authored-by: sundeep8967 <[email protected]>",
"author_name": "Hendrik Liebau",
"author_login": "unstubbable",
"date": "2026-09-02T13:57:40Z",
"url": "https://github.com/react/react/commit/8f0043721ef508420ae3855d8e9f910b1fec1c85",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "33b4555488b580c286dccde4ed52395241f1a1f5",
"message": "[DevTools] Use one commit for extension release inputs (#37307)
## Summary
`build-and-test.js` could feed three different commits into one release:
`git archive main` (not `HEAD`), an interactively chosen React CI build,
and `HEAD` saved as metadata. Firefox source review then could not
reproduce the zip.
Require a clean tree, resolve `HEAD` once, and use that hash for the
source archive, the experimental React download, and the metadata
printed for AMO. Drop the prompt that let those diverge.
Depends on #37305 and #37306.
## How did you test this change?
Build-script only. The release helper now errors on a dirty tree and
threads a single `git rev-parse HEAD` into archive, download, and
metadata.
Co-authored-by: Ruslan Lesiutin <[email protected]>",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-02T12:47:00Z",
"url": "https://github.com/react/react/commit/33b4555488b580c286dccde4ed52395241f1a1f5",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "e059aa36c07b441c9c21b2087d90f51b3d023783",
"message": "[DevTools] Remove build dates from extension manifests (#37306)
## Summary
The extension build writes `new Date().toLocaleDateString()` into
Chrome/Edge `version_name` and into every browser's manifest
description. That string changes with the calendar, timezone, and
locale, so a Firefox AMO rebuild on another day cannot match the
uploaded zip.
Stop stamping dates. `version_name` stays the value from the source
manifest (still updated by `prepare-release.js` on version bumps). The
description still records the commit from #37305.
Depends on #37305. Next: #37307.
## How did you test this change?
Build-script only. After this, `manifest.json` description is `Created
from revision <commit>.` and Chrome/Edge `version_name` is the committed
version string.
---------
Co-authored-by: Ruslan Lesiutin <[email protected]>",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-02T12:46:26Z",
"url": "https://github.com/react/react/commit/e059aa36c07b441c9c21b2087d90f51b3d023783",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "a7ef01ae4ad19971a0b83ef3dd377afeaef26816",
"message": "[DevTools] Use deterministic extension commit hashes (#37305)
## Summary
`git show --format=%h` is not stable: abbreviation length depends on
`core.abbrev` and how unique the prefix is in that clone. Two rebuilds
of the same commit can therefore embed different strings in
`DEVTOOLS_VERSION` and the extension manifest.
Always take the full hash (`%H`) and slice it to 10 characters so the
value is the same everywhere.
This also removes the `build/COMMIT_SHA` fallback used when Mozilla
rebuilds from a git archive (no `.git`). That path used a different
length (7) and a different source, so it could not match a git checkout
of the same commit. Firefox source review should rebuild from a checkout
of the commit in #37307, not from the tarball alone.
Stack: this PR → #37306 → #37307.
## How did you test this change?
Build-script only. `getGitCommit()` now returns `HEAD` sliced to 10
chars, independent of `core.abbrev`.
Co-authored-by: Ruslan Lesiutin <[email protected]>",
"author_name": "Ruslan Lesiutin",
"author_login": "hoxyq",
"date": "2026-09-02T12:28:31Z",
"url": "https://github.com/react/react/commit/a7ef01ae4ad19971a0b83ef3dd377afeaef26816",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "084f5f2457c90b88fedf04ccc8aabebfa988fad1",
"message": "[ci] Compare size against merge base (#37355)
Sizebot compared the pull request head build against the build of
`pull_request.base.sha`, which is the tip of the base branch at event
time, not the commit the pull request diverged from. The field's
semantics are undocumented in GitHub's API schema (the OpenAPI
description types it as a bare string); the observed behavior and the
compare API's `merge_base_commit` confirm the difference.
The difference between `pull_request.base.sha` and the merge base is
confirmed with an example in https://github.com/react/react/pull/37356
The sizebot job now resolves the merge-base through the compare API and
downloads the base build for that commit instead, so the report only
ever contains the pull request's own changes. The job gains `contents:
read` for the compare call.
When no base build can be downloaded for the merge-base, for example
because its artifacts aged out of the retention window or its run
failed, the sizebot job records a `base-build-not-found` result instead
of failing immediately. `render-comment.js` on the default branch
renders that as a warning comment naming the base commit and writes the
`sizebot-problem.txt` marker, so the comment workflow fails its check
after posting the warning, the same pattern already used for build
configuration drift. The sizebot job itself intentionally stays green: a
failed run would make the renderer discard the results and mask the
warning with a generic "did not complete" message.
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-09-02T10:29:06Z",
"url": "https://github.com/react/react/commit/084f5f2457c90b88fedf04ccc8aabebfa988fad1",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "d04798f2be8068f90813f917457a5b255ec6051d",
"message": "React Compiler: move compiled function bodies into AST instead of cloning (#37376)
tl;dr reduces memory churn by 7.8%, allocations by 4.1%, wall time by
~4%
## Summary
When compiled functions are written back to the AST,
`apply_compiled_functions` took a reference to a slice, and deep-cloned
each compiled body out of it. In theTS version this step assigns
references through Babel paths, which are essentially free. The Rust
port translated that as `.clone()` for safety, deep-copying the entire
codegen output for every compiled function.
Nothing needs these bodies after they are inserted, and the caller
already owns the vector. So this takes `compiled_fns` by value and moves
the data into the AST instead:
* `ReplaceFnVisitor` holds an `Option<CodegenFunction>` and moves it to
whatever arm matches
* Outlined function declarations move their id+params+body out of
`codegen_fn.outlined` rather than cloning them
* `needs_memo_import` is computed before the loop that consumes the
vector. Only the computation moved; the block that registers the import
stays where it was, so ordering and identifier numbering don't change.
This doesn't fully eliminate clones, just ones where it's easy to do a
move instead.
## How did you test this change?
All compiler fixtures pass with byte-identical output",
"author_name": "Andrew Imm",
"author_login": "andrewimm",
"date": "2026-09-02T05:11:26Z",
"url": "https://github.com/react/react/commit/d04798f2be8068f90813f917457a5b255ec6051d",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "469c4ec4d39464d64f64652fb1ef92fcc89e271c",
"message": "React Compiler: Store aliasing values in an inline set (#37366)
97.6% of the value sets tracked per identifier in mutation / aliasing
inference hold exactly one element, but each was a `FxHashSet`, meaning
each was a heap allocation.
Because the inference code retains a full state in each basic block,
these single-element hashsets were a major contributor to peak memory
allocation.
This replaces them with a small inline set inspired by smolvec /
tinyvec. Five values are stored inline, and any more spill to the heap.
This was only needed in **0.02%** of sets in my data corpus.
This also makes iteration order match the TS implementation. TS uses
`Set` and iterates in insertion order; the Fx set iterated in hash
order. This brings the two behaviors in line.
| Benchmark | Peak allocation | Allocation count | Wall time |
|------------------|-----------------------------|------------------|-----------|
| legacy/image.tsx | 33.40 -> 28.07 MiB (-16.0%) | -66.7% | -28.8% |
| next-client | 33.40 -> 28.07 (-16.0%) | -42.0% | -15.7% |
| devtools | 16.29 -> 14.25 (-12.5%) | -19.9% | -7.3% |
| fixtures | 9.41 -> 7.90 (-16.0%) | -7.3% | -3.3% |
| next-examples | 4.85 -> 4.85 ( 0.0%) | -4.8% | -1.6% |",
"author_name": "Andrew Imm",
"author_login": "andrewimm",
"date": "2026-09-02T05:10:29Z",
"url": "https://github.com/react/react/commit/469c4ec4d39464d64f64652fb1ef92fcc89e271c",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "0209ef8a77bcf423cb31029e050a0722a71ebd03",
"message": "[DevTools] Fix reconciliation of content with fallback Fiber (#37475)
## Summary
Alternative to #37280 that keeps the child-set assertion and instead
fixes the root cause.
The assertion "The children should not have changed if we pass in the
same set." fired while DevTools reconciled the hidden content tree of a
Suspense boundary that had just switched to its fallback.
`updateSuspenseChildrenRecursively` reconciles the content and the
fallback in two passes, but the previous-set lockstep pointer of the
content pass is not bounded. When a boundary is suspended on both sides
of a commit, the pointer advances from the previous content Offscreen
onto the previous fallback fragment, and the leftover-children check
reports `ShouldResetChildren` even though the fallback is reconciled in
the second pass by design.
For a boundary that is filtered from the tree, that flag propagates to
the parent child list, freezes its lockstep pointer, forces the
following sibling to be paired by alternate, and the instance scan
(which only matches the paired previous fiber) no longer finds the
existing instance, since instances track the current fiber. The subtree
below is then walked without its instance, which cascades into spurious
unmount and remount work and surfaces at the assertion in the filtered
same-child-set branch.
We're also avoiding creation of new backend instances in those
scenarios.
This change bounds the previous set of the content pass by the previous
fallback fragment via a new `prevLastChild` parameter, so the flag
disappears.
Closes #37280
## How did you test this change?
- cherry-picked test from #37280
---------
Co-authored-by: Ruslan Lesiutin <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-09-01T18:45:00Z",
"url": "https://github.com/react/react/commit/0209ef8a77bcf423cb31029e050a0722a71ebd03",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "fba23062c47c205839c1cff054ae8a5c380eec43",
"message": "Add Rust compiler crate publishing workflows (#37465)
## Summary
- configure the React Compiler Rust crates as a Cargo workspace with
shared package metadata and versioned internal dependencies
- add workflows to open a signed version-bump pull request and publish
the workspace through crates.io trusted publishing
- add release scripts and contributor documentation for versioning,
validation, and publishing
## Test plan
- Run `cargo check --locked --workspace` from `compiler/`.
- Run **(Compiler) Publish Rust Crates** from the Actions tab with **Dry
run** enabled; confirm every workspace crate packages successfully
without publishing.
- Run **(Compiler) Update Rust Crate Version** with a test version;
confirm it verifies one shared version and opens a signed version-bump
pull request containing the updated workspace manifest and lockfile.",
"author_name": "Will Binns-Smith",
"author_login": "wbinnssmith",
"date": "2026-09-01T17:04:34Z",
"url": "https://github.com/react/react/commit/fba23062c47c205839c1cff054ae8a5c380eec43",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "21c89c9fa087b23897999a74a378851e3c50b25c",
"message": "[DOM] Clean up Fragment listeners on signal abort (#37457)
Listeners registered with `options.signal` are supposed to be removed
when the signal is aborted.
Since `FragmentInstance` does not clean up its tracked listeners on
abort, previously removed listeners cannot be re-attached.",
"author_name": "chirokas",
"author_login": "chirokas",
"date": "2026-09-01T15:47:29Z",
"url": "https://github.com/react/react/commit/21c89c9fa087b23897999a74a378851e3c50b25c",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "065bc84eb50914fa1bc60983eac0b0b717186d74",
"message": "[DOM] Unobserve fragment IntersectionObserver targets after exit (#37408)
Fragment IntersectionObserver targets used to stay observed after a
child was removed so the exit record (isIntersecting: false) could still
fire, but that left the observer holding detached nodes. We now
unobserve ResizeObserver targets immediately, and delay
IntersectionObserver unobserve until after paint so the exit still
lands, then drop the strong ref.
If the same node is reinserted before that flush, we cancel the pending
unobserve so a later cleanup does not detach a child that’s still
visible.
Closes https://github.com/react/react/pull/37452/
Closes https://github.com/react/react/pull/37302
Fixes https://github.com/react/react/issues/37451",
"author_name": "Jack Pope",
"author_login": "jackpope",
"date": "2026-08-31T17:13:24Z",
"url": "https://github.com/react/react/commit/065bc84eb50914fa1bc60983eac0b0b717186d74",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "ff7445e636429ab26ce3d388535a79c845d88c94",
"message": "[DOM] Update HTML parser rules for new select parser (#34804)
Co-authored-by: Sebastian "Sebbie" Silbermann <[email protected]>",
"author_name": "Joey Arhar",
"author_login": "josepharhar",
"date": "2026-08-31T14:16:28Z",
"url": "https://github.com/react/react/commit/ff7445e636429ab26ce3d388535a79c845d88c94",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "2dc7da790d6388b95b83198ca9b588b2ad5f5c0b",
"message": "[test] Bump Jest to 30.4 (#37382)
Bumps Jest to latest 30.x
The `resolutions` pin that kept jsdom at 22.1.0 is removed, so the test
environment now runs the jsdom version that jest-environment-jsdom
declares (26.1.0 on Jest 30).
The matcher aliases that Jest 30 deleted are replaced with their
canonical forms across the test suites: `toBeCalled`, `toBeCalledTimes`,
`toBeCalledWith`, and `lastCalledWith` become the corresponding
`toHaveBeenCalled*` matchers, and `toThrowError` becomes `toThrow`. The
custom `toThrow` matcher override is removed in the PR below this one.
Jest 30 activates the `node` export condition for CommonJS requires in
every test environment, so in the jsdom-based Flight suites
`react-server-dom-webpack/client` now resolves to the Node build (which
requires an options argument) instead of the browser build. Those suites
now map the client entry to `client.browser` explicitly, matching the
existing mocks for the `server` and `static` entries, and the Turbopack
Node test uses `jest.requireActual` because `client` and `client.node`
now resolve to the same file, which otherwise made the mock factory
recurse. For the same reason `react-dom/static` resolves to the
lazily-initialized Node entry in source mode, so its version-mismatch
test is gated to build mode like the other server-entry tests.
The obsolete `prettierPath` override is dropped from the base Jest
config because Jest 30 works with Prettier 3 for inline snapshots, which
also fixes `yarn test -u` crashing on the repo's Prettier 3-only hermes
plugin, and the now unused `prettier-2` alias dependency is removed with
it. Snapshot files are regenerated for Jest 30's updated snapshot header
and formatting. One test now passes a number instead of a string to
`jest.advanceTimersByTime`, which fake-timers v13 no longer coerces.
---------
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-28T11:06:47Z",
"url": "https://github.com/react/react/commit/2dc7da790d6388b95b83198ca9b588b2ad5f5c0b",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "29d9d3184484b03cb0369e0494617207df777b7a",
"message": "[DOM] Copy `source` onto the synthetic toggle event (#37389)
`ToggleEvent` carries a `source` property pointing at the control that
opened or closed a popover, but `ToggleEventInterface` only lists
`newState` and `oldState`, so the synthetic event never copies it. An
`onToggle` handler reads `event.source` as `undefined` even when the
native event has it.
Adding `source` to the interface copies it off the native event the same
way `newState` and `oldState` are copied.",
"author_name": "Lazizbek Ergashev",
"author_login": "lazerg",
"date": "2026-08-26T19:45:29Z",
"url": "https://github.com/react/react/commit/29d9d3184484b03cb0369e0494617207df777b7a",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "269bd40a953a5339ad47c643f9b9dbce88ab878d",
"message": "[test] Remove the custom `toThrow` override for legacy V8 error messages (#37384)
The custom `toThrow` override in `scripts/jest/matchers/toThrow.js`
wrapped the built-in matcher to rewrite the pre-Node-17 V8 error message
format ("Cannot read property 'x' of undefined") into the modern one
("Cannot read properties of undefined (reading 'x')"), so the test suite
could run on Node 12 to 16.
On the Node versions this repo runs on (20 per `.nvmrc`, 24 in CI), V8
only ever produces the modern format, so the override is a passthrough.
Mostly removing this because the custom matcher deep-imports
`expect/build/toThrowMatchers`, which no longer resolves on Jest 30
because each Jest package is now bundled into a single file, so this
removal unblocks the Jest 30 upgrade stacked on top.
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-26T17:24:58Z",
"url": "https://github.com/react/react/commit/269bd40a953a5339ad47c643f9b9dbce88ab878d",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "a1124489a5e8f81e16ac957699a60038b965f502",
"message": "[DOM] Treat omitted Fragment Event listener options same as `capture: false` (#37251)
`FragmentInstance` tracks its event listeners so they can be applied to
children added later, and matches them by a normalized options identity.
Omitted options currently normalize to a different identity than an
explicit `false` or `{capture: false}`, even though both mean `capture:
false` per the `EventTarget` contract, where listener identity is the
tuple of type, callback, and capture flag. As a result, a listener added
without an options argument cannot be removed with an explicit
capture-false value (or the reverse).
This change normalizes omitted options to the same capture-false
identity as `false` and `{capture: false}`. The first commit adds a test
to the FragmentRef suite characterizing the current behavior; the second
commit contains the fix and the updated assertions.
---------
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Leo",
"author_login": "teamleaderleo",
"date": "2026-08-26T11:09:31Z",
"url": "https://github.com/react/react/commit/a1124489a5e8f81e16ac957699a60038b965f502",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "3c397fe76015d6988cdcb6f74aff978a3cc6a37a",
"message": "[test] Stop leaking mocked performance clocks into later test files (#37379)
Test files running in the Node.js Jest environment share the worker
process's `performance` object, because [`jest-environment-node`
installs it by
reference](https://github.com/jestjs/jest/blob/v29.7.0/packages/jest-environment-node/src/index.ts#L85-L103)
rather than by copy. When a test mocked the clock with
`Object.defineProperty(performance, 'now', ...)`, the mutation hit the
shared object and was never undone, since Jest only restores
`jest.spyOn` mocks when a file's runtime is torn down ([`jest-runtime`'s
`teardown()` calls
`restoreAllMocks()`](https://github.com/jestjs/jest/blob/v29.7.0/packages/jest-runtime/src/index.ts#L1358-L1359)).
Every subsequent test file in the same worker then observed the fake
clock, including jsdom-based files, whose [`performance.now()` subtracts
a window-creation timestamp from the shared object's
`now()`](https://github.com/jsdom/jsdom/blob/v22.1.0/lib/jsdom/living/hr-time/Performance-impl.js#L13-L14).
This change switches the six affected test files to
`jest.spyOn(performance, 'now')` and `jest.spyOn(performance,
'timeOrigin', 'get')`, which Jest restores automatically at teardown.
`ReactFlightDOMEdge-test.js` runs in jsdom and therefore did not leak,
but it used the same pattern and is converted for consistency.
This change is mostly for test hygiene. Was discovered while
investigating a flaky `{"time":NaN}` serialisation bug (e.g.
https://github.com/react/react/actions/runs/32878999825/job/97903912119)
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-26T10:49:48Z",
"url": "https://github.com/react/react/commit/3c397fe76015d6988cdcb6f74aff978a3cc6a37a",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "373d35eee53e3bcb0be4b31eea70f3b67ce5e4c1",
"message": "[ci] Pin build shard weights per run to keep worker assignments identical (#37373)
The build workers can restore different weights if they don't restore
the cache at the exact same time. The more time difference, the more
likely they restore different weights which could lead to some bundles
not being built at all (e.g.
https://github.com/react/react/actions/runs/32822851267).
A new job now restores the latest entry once per run and republishes it
as a per-run artifact. The new job sits adds no wall time because it
runs in parallel with `runtime_compiler_node_modules_cache`, which
already gates the build workers and takes about 30 seconds on a cache
hit, while the resolve job does strictly less work (no checkout, no Node
setup, a 5KB cache entry instead of the node_modules restore), so it
finishes first and the build workers start at the same time as before.
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-26T05:58:18Z",
"url": "https://github.com/react/react/commit/373d35eee53e3bcb0be4b31eea70f3b67ce5e4c1",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "f789f203e8b1e639330e51c828809f03619ac177",
"message": "[ci] Run Java setup in the background during build job setup (#37351)
In `build_and_lint`, `actions/setup-java` ran sequentially between
setup-node and the node_modules cache restore, but Java is only needed
by `yarn build` for the Closure Compiler bundles. This change marks the
setup-java step as a background step.
Setting up Java is mostly network (download) and CPU (unpack). It
overlaps with installing/restoring node_modules which is network and FS
work. So we aren't competing for resources that would make concurrently
running steps moot.
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-25T07:41:48Z",
"url": "https://github.com/react/react/commit/f789f203e8b1e639330e51c828809f03619ac177",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "5d0ccf23e49f40ac423d1951cc2744e96cc9390d",
"message": "[ci] Download build artifacts in the background during job setup (#37350)
Every downstream job in `runtime_build_and_test.yml` restored the 50
`_build_*` artifacts with `actions/download-artifact` only after
setup-node, the node_modules cache restore, and any installs had
completed, even though the download is independent of all of them.
This change marks the download as a [background
step](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstepsbackground)
started immediately after checkout, and adds an explicit `wait:
download_build` before the first step that reads `build/`.
The download starts after checkout because `actions/checkout` runs `git
clean`, which would wipe a previously downloaded `build/` directory. The
`sizebot` job is unchanged because its base-build download also writes
`./build` and would collide with a concurrent artifact restore.
This only shaves of a few seconds from wall time. It's more about
establishing precedent.
Co-authored-by: Claude Code (kimi-k3[1m]) <[email protected]>",
"author_name": "Sebastian "Sebbie" Silbermann",
"author_login": "eps1lon",
"date": "2026-08-25T07:40:18Z",
"url": "https://github.com/react/react/commit/5d0ccf23e49f40ac423d1951cc2744e96cc9390d",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
},
{
"sha": "6c3bd60a90cde43e12a6c0021de8f1ecb69491b9",
"message": "Revert "[rust-compiler] Bail out on nested TypeScript `this` parameters (#37232)" (#37363)
This reverts commit 35e64cf2bc4a980274ae0cb2a4bda11970560b7e.",
"author_name": "Will Binns-Smith",
"author_login": "wbinnssmith",
"date": "2026-08-24T22:52:03Z",
"url": "https://github.com/react/react/commit/6c3bd60a90cde43e12a6c0021de8f1ecb69491b9",
"scraped_at": "2026-09-08T17:13:03.657456+00:00"
}
]
}
GET
/v1/github/repos/{owner}/{repo}/commits1 credit / run VerifiedRepository Commits
Recent commits on a repository's default branch.
Handled for you:Rate Limit
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| owner | string | yes | Repository owner. |
| repo | string | yes | Repository name. |
| Advanced filters | |||
| limit | integer | no | Commits per page, 1-100. (default: 30) |