218 Commits
Author SHA1 Message Date
Sedat Çiftçi 731ae45ae6 Reduce allocations in VirtualizedList render and scroll path (#58593)
Summary:
`VirtualizedList`/`FlatList`/`SectionList` re-run a small amount of
bookkeeping on every render and on every scroll event (60–120 Hz on
ProMotion displays). This PR removes three allocations from those hot
paths without changing any observable behavior:

1. **`VirtualizedList.render` no longer builds a `Set` for
   `stickyHeaderIndices` on every render** when the prop is not provided
   (the common case). The Set is now only created when the prop is
   present; the two `.has()` lookups use optional access.
2. **`ChildListCollection.forEach` returns early when there are no nested
   child lists** (the common case) instead of allocating a
   `Map.values()` iterator. This is called from `_onScroll` and the four
   other scroll callbacks on every scroll event.
3. **`_orientation()` caches its result** and only rebuilds the object
   when the `horizontal` prop changes. `I18nManager.isRTL` is a
   module-load constant (only changes on app reload), so the cache is
   invalidated solely by the `horizontal` prop. The object is replaced,
   never mutated, which keeps `ListMetricsAggregator`'s field-based
   invalidation correct.

## Changelog:

[GENERAL][CHANGED] - Reduce allocations in the `VirtualizedList` render and scroll path (avoid per-render `Set` allocation for `stickyHeaderIndices`, per-scroll-event `Map` iterator for the empty nested-list collection, and per-call `orientation` object allocation)

Pull Request resolved: https://github.com/react/react-native/pull/58593

Test Plan:
- `yarn test packages/virtualized-lists` → 9 suites, 186 passed, 69
  snapshots:
  - `ChildListCollection-test.js` (new): forEach over populated/empty
    collection, removal, `forEachInCell`/`anyInCell`
  - `VirtualizedList-test.js`: `stickyHeaderIndices` not forwarded when
    the prop is absent (with `ListHeaderComponent`), forwarded when
    provided; orientation cache identity + invalidation on
    `horizontal` change
- `yarn flow-check` → 0 errors
- `yarn lint` → 0 errors, 0 warnings
- `yarn format-check` (changed files)

Micro-benchmark (Node v24, V8, 2M iterations, before vs after, same
machine; the real-world benefit is dominated by reduced GC pressure,
which is largest on low-end Android):

Reviewed By: Abbondanzo

Differential Revision: D121177373

Pulled By: javache

fbshipit-source-id: 1befd7e6d90fbd1fcea9c4cc8cf6d575c6c26111
2026-09-23 05:15:29 -07:00
Sam Zhou 4b6cd413d6 Replace legacy compat types with their new names in TS based lib.dom.d.ts in xplat: 2/n (#58643)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58643

X-link: https://github.com/react/metro/pull/1960

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D121075922

fbshipit-source-id: 0f4bdcb339e2c3987dc5942deb47c026668a9fa1
2026-09-22 12:04:26 -07:00
Rubén Norte 9b021cee52 Remove remaining package deep imports (#58604)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58604

Migrate the remaining package consumers to React Native root exports, documented secondary entry points, global web APIs, or package-relative implementation paths. Use feature flags instead of directly invoking web API setup helpers.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D120717573

fbshipit-source-id: bf1bdb8d49340dd0040a46eb388850bd4b8139fc
2026-09-21 11:31:38 -07:00
Sam Zhou 2761132459 Upgrade Flow in fbsource
Summary: Upgrade Flow.

Reviewed By: gkz

Differential Revision: D121017087

fbshipit-source-id: d5e9b717239db8c0369097d9d084c7450857f5d7
2026-09-21 09:49:37 -07:00
Aravind M Nair 0b1561a467 Fix misleading ListItemComponent JSDoc in VirtualizedList types (#58500)
Summary:
I added `ListItemComponent` to these types in https://github.com/react/react-native/issues/57754 and got the comment wrong. It says the component receives `index` and `separators` "in addition to the data provided to `renderItem`", which reads as if `renderItem` doesn't get them. It does. `_renderElement` in `VirtualizedListCellRenderer.js` passes the same `item`, `index` and `separators` to both.

This fixes that sentence and mentions the one thing that actually is different, which is precedence. When both are set, `ListItemComponent` wins and `_renderElement` logs a warning saying so.

## Changelog:

[INTERNAL] [FIXED] - Fix JSDoc for ListItemComponent in VirtualizedList types

Pull Request resolved: https://github.com/react/react-native/pull/58500

Test Plan:
Comment-only change in a `.d.ts`, no type changes. Checked the wording against `_renderElement`:

```js
if (ListItemComponent) {
  return (
    <ListItemComponent item={item} index={index} separators={this._separators} />
  );
}
if (renderItem) {
  return renderItem({item, index, separators: this._separators});
}
```

Reviewed By: cortinico

Differential Revision: D120077066

Pulled By: Abbondanzo

fbshipit-source-id: 489321ae950b169c9a985d18220d1ec84114e5fc
2026-09-16 07:33:19 -07:00
Amro Altahtamouni 0c35f57447 Fix VirtualizedSectionList.scrollToLocation off-by-one and sticky header offset (#58329)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58329

`VirtualizedSectionList.scrollToLocation`, and `SectionList` through its wrapper, mapped `itemIndex` to the underlying flat list without skipping the section header. As a result, `itemIndex: 0` targeted the header and every other item was one row early. Sticky-header compensation was also skipped for the first item, allowing the header to obscure it.

This change adds the header row to the flattened target index and always applies the sticky-header offset using the current section header metrics. The public API remains zero-based, but callers that compensated for the old behavior must remove that compensation.

Migration:
- Replace `itemIndex: n + 1` workarounds with `itemIndex: n`.
- Replace `itemIndex: data.length` last-item workarounds with `itemIndex: data.length - 1`.

Thanks to Marc Rousavy (mrousavy) for the diagnosis: https://github.com/react/react-native/issues/50143

Changelog:
[General][Breaking] - Fix `SectionList` and `VirtualizedSectionList` `scrollToLocation` to account for section headers and sticky headers correctly.

Reviewed By: javache, ryanfrawley

Differential Revision: D118547738

fbshipit-source-id: 4025d4bea38fcf69aa769f6f9260715b521ec7df
2026-09-15 16:36:07 -07:00
Rubén Norte b0b71421c1 React 19.3.0 sync int React Native OSS (#58446)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58446

Sync of React 19.3.0 into React Native

Changelog: [General][Changed] - Sync React 19.3.0 into React Native

jest_e2e[run_all_tests] bypass-github-export-checks

Reviewed By: fabriziocucci

Differential Revision: D119490598

fbshipit-source-id: 4a00bd01fd1a4b1c48ffcae182f1b88cd0cf9e06
2026-09-10 17:03:25 -07:00
Bao Nguyen a506ed66cc Expose ReactNativeFeatureFlags through react-private-interface (#57940)
Summary:
Fixes https://github.com/react/react-native/issues/57933.

`react-native/virtualized-lists` is published separately and imported `ReactNativeFeatureFlags` through `react-native/src/private/featureflags/ReactNativeFeatureFlags`, which is not listed in `react-native`'s `"exports"`. Metro therefore warned and fell back to file-based resolution whenever an app rendered a virtualized list.

Thanks huntie for the patch and the direction — this PR now applies it instead of the original approach:

- `ReactNativeFeatureFlags` is exposed on the existing private package boundary, `react-native/react-private-interface` (both the runtime getter and the `.js.flow` re-export);
- `VirtualizedList.js` and `VirtualizeUtils.js` import it from there.

No new `src/private/*` subpath is exported, and the feature-flag singleton is unchanged.

Per your review, the `scripts/monorepo-tests/__tests__/check-packages-test.js` and `scripts/shared/monorepoUtils.js` changes have been dropped — the PR is now just the patch above. Happy to look at enabling `react-native/no-deep-imports` on `virtualized-lists` as a follow-up if that's wanted.

`VirtualizeUtils.js` is included alongside `VirtualizedList.js` because it carried the same runtime deep import. The remaining occurrences are out of scope: the four in `react-native/jest-preset` are all `import type` and are erased before resolution, and the one in `VirtualizeUtils-test.js` is not shipped (`virtualized-lists` excludes `**/__tests__/**` from `files`).

## Changelog:

[GENERAL] [FIXED] - Fix the Metro package-exports warning caused by `react-native/virtualized-lists` importing an unexported React Native subpath.

Pull Request resolved: https://github.com/react/react-native/pull/57940

Test Plan:
No new test is added. The existing `virtualized-lists` suites already cover this route, because `VirtualizeUtils`/`VirtualizedList` read the flags at runtime through the new boundary.

Counterfactual — dropping only the `ReactNativeFeatureFlags` getter and its `import typeof` from `react-private-interface.js`, keeping the two `virtualized-lists` imports:

```text
TypeError: Cannot read properties of undefined (reading 'fixVirtualizeListCollapseWindowSize')

      182 |     let lastWillAddMore;
      183 |
    > 184 |     if (ReactNativeFeatureFlags.fixVirtualizeListCollapseWindowSize()) {
          |                                ^

      at computeWindowedRenderLimits (packages/virtualized-lists/Lists/VirtualizeUtils.js:184:32)
      at Object.<anonymous> (packages/virtualized-lists/Lists/__tests__/VirtualizeUtils-test.js:261:47)

Test Suites: 2 failed, 6 passed, 8 total
Tests:       20 failed, 1 skipped, 151 passed, 172 total
```

Restoring the getter makes it green again.

```text
$ yarn jest packages/virtualized-lists scripts/monorepo-tests packages/react-native/Libraries/ReactPrivate --runInBand
Test Suites: 9 passed, 9 total
Tests:       1 skipped, 176 passed, 177 total
Snapshots:   69 passed, 69 total

$ yarn flow-check
Found 0 errors

$ yarn lint
$ eslint --max-warnings 0 .
Done in 10.23s.
```

Reviewed By: javache

Differential Revision: D119164284

Pulled By: cortinico

fbshipit-source-id: 1e8ae3b85ae7fb28c55f207f887a97aad85b563c
2026-09-08 07:34:16 -07:00
Sam Zhou f072ddb17c Deploy 0.331.0 to xplat (#58332)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58332

[changelog](https://github.com/facebook/flow/blob/main/Changelog.md)
Changelog: [Internal]

Reviewed By: panagosg7

Differential Revision: D118823256

fbshipit-source-id: 11d1e53dad7985686fd97a2aa771cd5c5ece7e09
2026-09-04 12:16:47 -07:00
Peter Abbondanzo c057b1fa01 Fix viewability for zero-sized lists (#58074)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58074

Pull Request resolved: https://github.com/react/react-native/pull/58000

VirtualizedList viewability only considered the scroll-axis viewport length. A horizontal list with zero height could therefore report items as viewable. Record the cross-axis length in the same scroll metrics snapshot and require both viewport dimensions to be non-zero for viewability.

Changelog:
[General][Fixed] - Prevent zero-sized lists from reporting viewable items

Reviewed By: zeyap

Differential Revision: D116699497

fbshipit-source-id: 29f8ceaf0e5ffe0b79c807aa749240558cfe115a
2026-08-24 04:22:13 -07:00
generatedunixname89002005232357 6c4cf29689 Revert D116356139: Fix viewability for zero-sized lists
Differential Revision:
D116356139

Original commit changeset: 77c1b61bddfd

Original Phabricator Diff: D116356139

fbshipit-source-id: 427c3f65354fb0b74191d3a3f1f4db5d51d9c9d1
2026-08-19 12:38:38 -07:00
Peter Abbondanzo 57c8285d40 Fix viewability for zero-sized lists (#58000)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58000

VirtualizedList viewability only considered the scroll-axis viewport length. A horizontal list with zero height could therefore report items as viewable. Record the cross-axis length in the same scroll metrics snapshot and require both viewport dimensions to be non-zero for viewability.

Changelog:
[General][Fixed] - Prevent zero-sized lists from reporting viewable items

Reviewed By: zeyap, christophpurrer

Differential Revision: D116356139

fbshipit-source-id: 77c1b61bddfde1dcac9e670ddab80915ef42149a
2026-08-19 12:11:11 -07:00
Rohan Kulkarni 5cb65244dc Fix maintainVisibleContentPosition with rapid data updates (#53542) (#57955)
Summary:
Fixes https://github.com/react/react-native/issues/53542

**Problem:** `maintainVisibleContentPosition` fails when FlatList data is updated rapidly with prepends in quick succession (e.g., chat receiving messages). After 2 prepends before native scroll drains, render window stays frozen, `onViewableItemsChanged` suppressed, `onEndReached` never fires.

**Root cause:** `pendingScrollUpdateCount` assumption is structurally unsound – it increments by 1 per prepend in `getDerivedStateFromProps` (0→1→2) but native scroll events are dispatched as unique events that coalesce. Verified in C++:
- `ScrollViewEventEmitter.cpp:13` – `onScroll` dispatched with `dispatchUniqueEvent("scroll", ...)`
- `EventQueue.cpp:29-50` – unique event whose target+type matches existing replaces in place (line 49) instead of appending
So N scroll events emitted before queue flush deliver exactly 1 to JS. Single coalesced event drains 2→1 leaving blocked. Also leak when JS predicate fires (old key found at new index) but native declines to adjust (tag recycled, view deleted, delta ≤0.5, clamped).

**Fix (1 file, 2 lines core):** Clamp pending to at most 1 and drain to 0 on any scroll:
- `pendingScrollUpdateCount: 1` instead of `prev+1` – prevents accumulation during rapid prepends
- `setState({pendingScrollUpdateCount: 0})` instead of `-1` – single coalesced scroll unblocks

This turns "stuck at N" into unblocked after next scroll, fixing frozen window / viewability / onEndReached for rapid updates. For leak path where native declines (no scroll ever), flag would still be stranded at 1 – addressed by boolean rename + escape hatch in follow-up, but this PR already strictly improves and matches existing tests that drain 0→1→0.

## Changelog:
[GENERAL] [FIXED] - Fix maintainVisibleContentPosition with rapid data updates (https://github.com/react/react-native/issues/53542)

Pull Request resolved: https://github.com/react/react-native/pull/57955

Test Plan:
**Jest (VirtualizedList):**
```bash
yarn jest --watchman=false packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js --no-coverage --ci
# Before: new coalesced test fails with pending 1
# After: 83 passed (82 existing + 1 new rapid prepends with coalesced scroll), 1 skipped, 59 snapshots
```

**New test ( regression for https://github.com/react/react-native/issues/53542 ):**
- Simulates 2 rapid prepends WITHOUT intermediate scroll (5 + 3 items)
- Only 1 coalesced scroll event (delta 8*ITEM_HEIGHT)
- Asserts `pendingScrollUpdateCount === 0` (fails on main with 1) and `firstVisibleItemKey` not null

**Existing MVCP tests still pass:**
- `handles maintainVisibleContentPosition`
- `handles multiple rapid prepends` (separate scroll per prepend)
- `delta stays bounded`
- `minIndexForVisible >0` and `inverted`

**Lint:**
```bash
yarn lint
# Done (max-warnings 0)
```

Closes https://github.com/react/react-native/issues/53542

Reviewed By: javache

Differential Revision: D115907610

Pulled By: fabriziocucci

fbshipit-source-id: 0cd59b35d7c43803a000b93779cd84c9c4202053
2026-08-17 04:55:47 -07:00
Riccardo Cipolleschi 1c4a46f4e3 Ignore stale minimum-view-time viewability updates (#57923)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57923

Changelog: [General][Fixed] - Ignore stale viewability updates while enforcing minimum view time

Minimum view-time callbacks can outlive a newer viewport update. During initial layout, callbacks for intermediate viewport snapshots can fire after the current snapshot and replace the correct visible-item set. Discard callbacks whose captured visible-index set is no longer current, and cover the transition with a unit test.

Reviewed By: Abbondanzo

Differential Revision: D115740467

fbshipit-source-id: 0a308dbc57c1d1fc5b2b669d998d1d9f8f1495f1
2026-08-13 06:59:30 -07:00
Minh Vu e59a1d252c fix(virtualized-lists): invalidate content length on orientation change (#57871)
Summary:
When a list changes between vertical and horizontal layouts, `ListMetricsAggregator` resets its cell measurements but keeps `_contentLength`. That value belongs to the old scrolling axis. In horizontal RTL mode, it can then be used to calculate a cell offset before the new content layout is observed.

This clears `_contentLength` during horizontal orientation changes so RTL calculations wait for the new content length. The reset was present in the original orientation invalidation logic and was removed when bottom-up layout support was removed.

## Changelog:

[GENERAL] [FIXED] - Invalidate list content length when orientation changes.

Pull Request resolved: https://github.com/react/react-native/pull/57871

Test Plan:
- Added regression coverage for vertical to horizontal content length invalidation.
- Verified horizontal RTL metrics throw until new content layout is observed.
- Ran `yarn jest packages/virtualized-lists/Lists/__tests__/ListMetricsAggregator-test.js --runInBand`.
- Ran Prettier and targeted ESLint checks.

Reviewed By: christophpurrer

Differential Revision: D115586644

Pulled By: fabriziocucci

fbshipit-source-id: 6c0f1b435575c080444b72381f7ce56ae3f69a15
2026-08-12 12:37:41 -07:00
Aravind M Nair 5306e9229c Add missing ListItemComponent prop to VirtualizedList/FlatList/SectionList TypeScript types (#57754)
Summary:
`ListItemComponent` is a valid prop on `FlatList`, `SectionList` and `VirtualizedList` (it's in the Flow types in `VirtualizedListProps.js`), but it's missing from the `.d.ts`, so TypeScript errors on it even though it works at runtime.

Added it to `VirtualizedListWithoutRenderItemProps` next to the other `List*Component` props, so all three inherit it.

## Changelog:

[GENERAL] [ADDED] - Add missing ListItemComponent type to VirtualizedList props

Pull Request resolved: https://github.com/react/react-native/pull/57754

Test Plan:
Errors on `main`, type-checks with the change:

```tsx
<FlatList data={[]} ListItemComponent={MyItem} />
```

Type-only, addition only, no runtime changes.

Reviewed By: Abbondanzo

Differential Revision: D114061127

Pulled By: fabriziocucci

fbshipit-source-id: e843645a93b2320370829e8fd86deda078d6852a
2026-07-30 03:38:24 -07:00
Peter Abbondanzo ca750feefb Format React Native maintain-visible tests (#57747)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57747

Format maintain-visible Maestro tests and the virtualized lists design documentation with Prettier.

Currently failing main checks:
```
Run yarn run format-check
yarn run v1.22.22
$ prettier --list-different "./**/*.{js,md,yml,ts,tsx}"
packages/rn-tester/.maestro/flatlist-append-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-complex-mutations-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-delete-anchor-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-delete-middle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-empty-list-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-first-prepend-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-horizontal-add50-reset-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-horizontal-inverted-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-horizontal-inverted-recycle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-horizontal-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-horizontal-recycle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-inverted-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-inverted-recycle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-momentum-scroll-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-orientation-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-prepend-delete-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-pull-to-refresh-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-rapid-prepends-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-recycle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-scrolltooffset-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-throttle-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-variable-height-first-prepend-maintainvisible.yml
packages/rn-tester/.maestro/flatlist-variable-height-maintainvisible.yml
packages/rn-tester/.maestro/scrollview-minindex-maintainvisible.yml
packages/rn-tester/.maestro/scrollview-threshold-maintainvisible.yml
packages/virtualized-lists/__docs__/DESIGN.md
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Process completed with exit code 1.
```

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D113954762

fbshipit-source-id: 26a0e77f81395da0ff6e7673eb10887ab20ecb97
2026-07-28 14:25:40 -07:00
Aaron Oneal 3b90423076 Fix maintainVisibleContentPosition calculations and add tests + docs [fixes #25239] (#57294)
Summary:
This PR fixes three bugs in the VirtualizedLists maintainVisibleContentPosition (MVCP) feature and adds comprehensive documentation for the architecture and testing approach.

It was intended to address the reports in https://github.com/react/react-native/issues/25239 but may also address others like https://github.com/react/react-native/issues/42915 and https://github.com/react/react-native/issues/53542.

**Bug Fixes:**

1. **Android: MVCP scroll position stale due to event throttle** — Scroll events during scroll animations and MVCP adjustments were being throttled by `scrollEventThrottle` (default 16ms, tests use 500ms), preventing the JS-side scroll offset state from updating to reflect the actual native scroll position. This caused MVCP delta calculations to use stale JS offset values, resulting in incorrect scroll corrections (e.g., delta of 143 instead of expected 44). Fixed by adding `emitScrollEventNoThrottle()` that bypasses the throttle after scroll animations end and after MVCP adjustments.

2. **iOS: MVCP correction fails when anchor view is deleted or recycled** — `_adjustForMaintainVisibleContentPosition` could apply a delta from a stale view's frame after `scrollToOffset(0)` during reset, resulting in incorrect offset (e.g., ~3876 instead of 0). Fixed by adding three abort conditions: nil check, tag check (detects view recycling), and superview check (detects view deletion).

3. **VirtualizedLists: Cell metrics not cleared on orientation change** — `ListMetricsAggregator` didn't clear `_cellMetrics` on orientation change, causing new cells to find stale entries and `_averageCellLength` to become NaN or Infinity. Also added a guard against divide-by-zero when `_measuredCellsCount` is 0. Both bugs broke scroll position calculations, content length estimates, and index-to-offset conversions.

**Documentation:**

Added documentation file under `packages/virtualized-lists/__docs__/`:
- `DESIGN.md` — MVCP architecture and implementation details

## Changelog:

[ANDROID] [FIXED] - Fix MVCP scroll position not updating due to scrollEventThrottle during animations and adjustments

[IOS] [FIXED] - Fix MVCP correction failing when anchor view is deleted or recycled during mount operations

[GENERAL] [FIXED] - Fix ListMetricsAggregator cell metrics not clearing on orientation change and guard against divide-by-zero

[INTERNAL] [ADDED] - Document MVCP architecture, history, and test coverage in `__docs__/`

Pull Request resolved: https://github.com/react/react-native/pull/57294

Test Plan:
- Maestro test `flatlist-throttle-maintainvisible.yml` passes — delta is within expected range on Android with 500ms throttle
- iOS: Verified MVCP correction works correctly after reset/clear, item deletion, and view recycling scenarios
- Verified cell metrics are correctly reset on orientation change (vertical ↔ horizontal)
- Verified `_averageCellLength` is guarded against divide-by-zero when no cells have been measured yet

Reviewed By: cipolleschi, javache

Differential Revision: D112200548

Pulled By: Abbondanzo

fbshipit-source-id: 27d55965707a2a24d08c80921012e6c359f2e9f9
2026-07-28 13:18:22 -07:00
Alex Hunt 89300acb9c Migrate Node.js builtin imports to node: scheme (#57611)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57611

Directly follows D112733139 (Metro).

**Motivation**

- New Node builtins are *only* available under the prefix (e.g. `node:sqlite`), as this allows Node to introduce them without ecosystem-breaking changes, so this is the direction of travel and the only choice that'll allow consistency.
- Encouraging them and grouping them separately makes it easier to reason about a module's 3rd party dependencies.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D112803684

fbshipit-source-id: 40668d746a7151b3aa4800ff8af997902a18d198
2026-07-21 09:01:41 -07:00
Rubén Norte bbb5be9b41 Remove SceneTracker module and its use in AppRegistry (#57417)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57417

`SceneTracker` was a small helper in `Libraries/Utilities` that tracked the active navigation scene. It was only ever consumed through a deep import and was never part of the public API. This removes it from the React Native package and moves scene tracking to the application layer that actually depends on it.

As part of this, `AppRegistry.runApplication` no longer sets the active scene to the app key. To let the application layer preserve that behavior for surfaces launched by app key, `WrapperComponentProvider` now receives the app key as an optional second argument.

Changelog: [General][Breaking] - Remove the `SceneTracker` module from `Libraries/Utilities`, stop setting the active scene from `AppRegistry.runApplication`, and pass the app key as an optional second argument to `WrapperComponentProvider`

Reviewed By: huntie, javache

Differential Revision: D110471317

fbshipit-source-id: 28d44c74d2cff7926094959f26aa1ed0bf4be9ad
2026-07-14 09:31:46 -07:00
Sam Zhou a016e94b59 Redo D111190630: Stop using prettier-plugin-hermes-parser for formatting (#57537)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57537

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D111829105

fbshipit-source-id: 3309a22e737f68aca2d8d19f49e56bad955e5377
2026-07-13 17:48:27 -07:00
generatedunixname89002005232357 65af886291 Revert D111190630: Stop using prettier-plugin-hermes-parser for formatting
Differential Revision:
D111190630

Original commit changeset: e7ed7ee6f057

Original Phabricator Diff: D111190630

fbshipit-source-id: 49e33587fa084c181d64d35ac6bcf6ab73edfa5f
2026-07-13 16:42:37 -07:00
Sam Zhou 2235b8ec3f Stop using prettier-plugin-hermes-parser for formatting (#57505)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57505

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D111190630

fbshipit-source-id: e7ed7ee6f05701fbdaad1c8fad58c47f48344487
2026-07-13 15:57:35 -07:00
Alex Hunt c948b61c05 Enable Strict TS API by default (#57490)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57490

See [**RFC0894: Removing deep imports from react-native**](https://github.com/react-native-community/discussions-and-proposals/pull/894)

This is the **big switch** to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native.

**Opt-in → opt-out**

After this change, the main `react-native` package resolves its `"types"` entry points only to `types_generated/index.d.ts` — with no other subpaths available.

The new `"react-native-legacy-deep-imports"` condition maps to legacy `types/` and `Libraries/*.d.ts` sources.

**Impact limitation**: For this stage of rollout, the `"default"` condition continues to resolve to source files. Only TypeScript is affected.

**How to opt out**

Opposite of today's opt-in, which we will update in [the docs](https://reactnative.dev/docs/strict-typescript-api). Again, the only impact area today is **TypeScript**.

```json5
// tsconfig.json
{
  "extends": "react-native/typescript-config",
  "compilerOptions": {
    ...
    "customConditions": ["react-native-legacy-deep-imports"]
  }
}
```

**Other changes**

- Drop `react-native/typescript-config/strict` entry point, update README.
- Update `__typetests__`.

**Rollout plan**

**Target release: 0.87**. This and the contributing stack will be cherry picked for RC1.

- We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate.
- The Strict API includes a number of **intentional breaking changes**, and docs have been kept up to date.
- We're shipping a `/migrate-to-strict-api` skill to migrate via agents, see https://github.com/react-native-community/skills/pull/3.

**What's improved since 0.80?**

Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state.

Most notably:

- 21+ new/updated root APIs and fixes due to community feedback ([discussion](https://github.com/react-native-community/discussions-and-proposals/discussions/893), [PRs](https://github.com/react/react-native/pulls?q=is%3Apr%20label%3A%22JS%20API%20stabilization%20(1.0)%22%20is%3Aclosed)).
- Upstream encapsulation blocker in TypeScript, fixed in 6.0 (https://github.com/react/react-native/issues/53565).
- Tailwind/Uniwind compatibility (`interface` types for props).
- `*Instance` ref type exports for all built-in components (https://github.com/react-native-community/discussions-and-proposals/pull/1003).
- Fixes to previously mistyped, high impact APIs, such as `Appearance`.
- New subpath entry points for `asset-registry`, `setup-env`, and others.
- Refinements to doc comments/type translation build.

**Rollback plan**

Revert this diff.

IMPORTANT: We'll adopt a policy of **super-eager rollback**, if there are any unsolvable issues during the RC phase.

Changelog:
[General][Breaking] - React Native's default JavaScript API is now the [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api). Use `customConditions: ["react-native-legacy-deep-imports"]` to opt out.

Reviewed By: cortinico

Differential Revision: D110458670

fbshipit-source-id: 4b0e0b458a5f895f783d6d936e7b11ccff2df076
2026-07-10 09:28:17 -07:00
Sam Zhou 537d867316 Bump to latest prettier (#57473)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57473

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D110952668

fbshipit-source-id: a2278dbe978b42d42f57ddea10a947703a181797
2026-07-08 05:24:04 -07:00
Alex Hunt ffe3f79495 Standardize secondary package READMEs (#57273)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57273

**Motivation**

A README is the first thing an npm visitor sees on each package; internal-repo boilerplate like the "Testing" sections and the "We're using yarn…" note doesn't belong on a published package page.

**Changes**

- Standardize every README: a `# react-native/<name>` heading, a user-facing description, and a blue version badge plus a green monthly-downloads badge.
- Keep the "internal dependency" prelude only on `community-cli-plugin`, `virtualized-lists`, and `js-polyfills`.
- Drop the monorepo-template "Testing" sections and yarn note.
- Rework `metro-config` around the Configuring Metro guide; add missing READMEs for `metro-babel-transformer` and `popup-menu-android`.

Changelog: [Internal]

Reviewed By: emily8rown

Differential Revision: D109017270

fbshipit-source-id: 6208294c4ad2e6235a6605ae54f22d730f0476e7
2026-06-18 07:04:44 -07:00
Rob Hogan dcbd8608a6 Update package.json references to GitHub org "facebook" -> "react" (#57258)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57258

Reflecting the move to https://github.com/react/react-native , update references in first-party `package.json`s

The `repository.url` field in particular is load-bearing for Trusted Publish.

Changelog: [Internal]

___

Reviewed By: fabriziocucci

Differential Revision: D108986410

fbshipit-source-id: 78513ffefc32ddf417dc1479a4834ebc44240080
2026-06-18 02:00:52 -07:00
Tarık fe53279889 Avoid sticky header scans for non-sticky VirtualizedLists (#57210)
Summary:
`VirtualizedList._createRenderMask` always did the sticky-header lookup, even when there were no sticky headers. For a large list scrolled far from the top, that meant walking backward from the first visible item toward index 0 on every render-mask update.

This changes that path to:

- skip the lookup when `stickyHeaderIndices` is missing or empty
- when sticky headers exist, scan the sticky header indices and pick the closest one above the viewport
- keep `ListHeaderComponent` offset handling and integer-index behavior

## Changelog:

[GENERAL][CHANGED] - Speed up VirtualizedList render-mask creation for large lists by avoiding the old backward sticky-header scan when sticky headers are missing or sparse.

## Affected components

This is inside `VirtualizedList`, so the affected callers are:

- `VirtualizedList`
- `FlatList`, because it renders through `VirtualizedList`
- `VirtualizedSectionList` / `SectionList`, because section lists also render through this path

`stickyHeaderIndices` does not need to be set to get the no-sticky win. A normal `FlatList` with no sticky headers still used to pay the backward scan. With this change, that case exits before the sticky-header helper runs.

When `stickyHeaderIndices` is set, the lookup changes from scanning item indices back toward 0 to scanning only the sticky header index array. The size of the win then depends on how many sticky headers are configured.

## Benchmark

Benchmark command:

```sh
yarn fantom --benchmarks packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js --runInBand
```

Fantom Hermes benchmark, 100 samples per case. Values below are median latency for `VirtualizedList._createRenderMask` when the viewport is near the end of the list.

Per-call values are under 1 second, so they stay in milliseconds. For 1,000 render-mask updates, values over 1 second are shown in seconds.

| Case | One update before | One update after | Speedup | 1,000 updates before | 1,000 updates after |
| --- | ---: | ---: | ---: | ---: | ---: |
| 100k rows, no sticky headers | 2.664 ms | 0.0034 ms | 780x | 2.66 s | 3.42 ms |
| 100k rows, empty sticky headers | 2.632 ms | 0.0033 ms | 800x | 2.63 s | 3.29 ms |
| 100k rows, one top sticky header | 2.705 ms | 0.0054 ms | 499x | 2.71 s | 5.42 ms |
| 250k rows, no sticky headers | 6.543 ms | 0.0035 ms | 1,892x | 6.54 s | 3.46 ms |
| 250k rows, empty sticky headers | 6.579 ms | 0.0033 ms | 2,024x | 6.58 s | 3.25 ms |
| 250k rows, one top sticky header | 6.796 ms | 0.0053 ms | 1,294x | 6.80 s | 5.25 ms |
| 500k rows, no sticky headers | 13.173 ms | 0.0033 ms | 4,002x | 13.17 s | 3.29 ms |
| 500k rows, empty sticky headers | 13.073 ms | 0.0033 ms | 3,997x | 13.07 s | 3.27 ms |
| 500k rows, one top sticky header | 13.444 ms | 0.0054 ms | 2,511x | 13.44 s | 5.35 ms |
| 750k rows, no sticky headers | 19.524 ms | 0.0033 ms | 6,008x | 19.52 s | 3.25 ms |
| 750k rows, empty sticky headers | 19.572 ms | 0.0033 ms | 6,022x | 19.57 s | 3.25 ms |
| 750k rows, one top sticky header | 20.304 ms | 0.0054 ms | 3,778x | 20.30 s | 5.37 ms |
| 1m rows, no sticky headers | 26.190 ms | 0.0033 ms | 8,058x | 26.19 s | 3.25 ms |
| 1m rows, empty sticky headers | 26.039 ms | 0.0033 ms | 8,012x | 26.04 s | 3.25 ms |
| 1m rows, one top sticky header | 26.855 ms | 0.0053 ms | 5,075x | 26.86 s | 5.29 ms |

This benchmark is intentionally focused on this helper. It does not claim the whole app or whole list render becomes thousands of times faster. It shows that this hot helper is no longer proportional to the scroll distance from the top of the list.

Pull Request resolved: https://github.com/react/react-native/pull/57210

Test Plan:
```sh
yarn jest packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js packages/virtualized-lists/Lists/__tests__/VirtualizedSectionList-test.js packages/react-native/Libraries/Lists/__tests__/FlatList-test.js --runInBand
```

Passed: 3 suites, 101 tests, 1 skipped, 76 snapshots.

```sh
yarn fantom packages/react-native/Libraries/Lists/__tests__/FlatList-itest.js packages/react-native/Libraries/Lists/__tests__/SectionList-itest.js --runInBand
```

Passed: 2 suites, 64 tests.

```sh
yarn flow check
```

Passed: no errors.

```sh
./node_modules/.bin/eslint packages/virtualized-lists/Lists/VirtualizedList.js packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js packages/react-native/Libraries/Lists/__tests__/VirtualizedList-stickyHeaders-benchmark-itest.js
```

Passed.

```sh
git diff --check
```

Passed.

Reviewed By: javache

Differential Revision: D108890210

Pulled By: Abbondanzo

fbshipit-source-id: 7548ba29d77ac14a609665356ab7d09662820abe
2026-06-17 12:48:06 -07:00
Alex Hunt a0d39e7a9c Bump minimum Node.js version to 22 (#56887)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56887

Drop support for Node.js 20. The minimum supported version is now `^22.13.0 || ^24.3.0 || >= 26.0.0`.

Node.js 20 reached end-of-life in April 2026 and is no longer actively maintained. This aligns React Native with the upcoming Metro requirement.

Changelog:
[General][Breaking] - Require Node.js >= 22.13.0

Reviewed By: christophpurrer, cortinico

Differential Revision: D105685641

fbshipit-source-id: f490e5a13e4289daba98c4d56dd8fdd341aef0db
2026-05-19 11:53:54 -07:00
Fabrizio Duroni c0bf1549c2 Re-enabled VirtualizedList "retains batch render region when an item is appended" test (#56653)
Summary:
This PR is a follow-up of https://github.com/facebook/react-native/issues/56358, in order to improve and VirtualizedList tests.
I re-enabled the skipped test `retains batch render region when an item is appended`.
With React 19, the previous approach that was using `jest.runAllTimersAsync` in this test path was unstable because the pre-update render region could still be processing updates.
I adopted the same approach used in https://github.com/facebook/react-native/issues/56358 by introducing a small helper function, `advanceUntilLastCellIndexRendered`, which advances timers one step at a time and stops when the expected state is reached: `cellsAroundViewport.last === items.length - 1`.

As part of this follow-up, I also aligned `advanceUntilRenderAreaChanged` to use performNextBatch for consistent stepwise timer advancement.

## Changelog:

[GENERAL][FIXED] - Re-enabled VirtualizedList "retains batch render region when an item is appended" tes

Pull Request resolved: https://github.com/facebook/react-native/pull/56653

Test Plan:
- Ran the VirtualizedList-test.js and verified all test cases passed.
- Verified test modification correctness by intentionally breaking the related snapshot and check that it is breaking/it is failing.

Reviewed By: cortinico

Differential Revision: D104291284

Pulled By: Abbondanzo

fbshipit-source-id: e32f8707a837a1805ce130d526768228f684e3e7
2026-05-08 09:56:47 -07:00
Rob Hogan 783f45746e Bump packages to 0.87.0-main following 0.86 cut (#56716)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56716

Now that we've cut 0.86, bump all versions on `main` ready for the 0.87 cut.

Changelog: [Internal]

Reviewed By: cortinico, fabriziocucci

Differential Revision: D104219534

fbshipit-source-id: 86f2ebe5b44f67608a7a9495bf9840f2cdd52e5b
2026-05-07 07:23:06 -07:00
Fabrizio Duroni 9b966d1d8f Improve VirtualizedList test for render area change with initialScrollIndex non zero (#56358)
Summary:
In `VirtualizedList-test.js`, the test `adjusts render area with non-zero initialScrollIndex` relied on a hardcoded timer  `jest.advanceTimersToNextTimer(3)` to wait for `VirtualizedList` to expand its render window when `initialScrollIndex` is passed as prop.

When `initialScrollIndex` > 0, `VirtualizedList` blocks the render area recalculation until a valid scroll event is received (`pendingScrollUpdateCount`). Once unblocked, a series of batched `setTimeout` callbacks is scheduled through `_scheduleCellsToRenderUpdate` (triggered from `_onLayout`, `_onContentSizeChange`, and then from `componentDidUpdate`). Those callbacks eventually lead to updates of `cellsAroundViewport.first/last` in `_updateCellsToRender`.
The `cellsAroundViewport` property of `VirtualizedList` describes the currently rendered range of item indices, including overscan items outside the visible viewport. The hardcoded magic number 3 was effectively tied to how many internal timer callbacks fired from the chain of calls above.

So I replaced the fixed count (`3`) with a small helper function, `advanceUntilRenderAreaChanged`,  that advances timers one tick at a time (every time in its own act to let the `VirtualizedList` component update) and stops as soon as `cellsAroundViewport` changes.
If this doesn't happened, I trigger a specific error to report that the render area did not been change as expected.

## Changelog:

[GENERAL][FIXED] - Improve render area change with initialScrollIndex non zero test in VirtualizedList to avoid magic numbers timers

Pull Request resolved: https://github.com/facebook/react-native/pull/56358

Test Plan:
- Ran the `VirtualizedList-test.js` and verified all test cases passed.
- Verified test modification correctness by intentionally breaking the related snapshot and check that it is breaking/it is failing.

Reviewed By: zeyap

Differential Revision: D100649294

Pulled By: Abbondanzo

fbshipit-source-id: fc04c6c44fa311f9ef7263ceeea3bac3f44a8e13
2026-04-15 11:19:18 -07:00
Sam Zhou d0a1efbec3 Change all remaining flow legacy casting syntax to modern one (#56259)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56259

Change all remaining flow legacy casting syntax to modern one.

Changelog: [Internal]

Reviewed By: panagosg7

Differential Revision: D98565441

fbshipit-source-id: 39b64397689d1ce05647d6a029b7c903fff1a1f6
2026-03-27 17:58:15 -07:00
Alan Lee bbaabe6a16 Bump packages for next release (#55946)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55946

Follows the recent `0.85-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.86.0-main`

Reviewed By: cortinico

Differential Revision: D95410323

fbshipit-source-id: dacfee00f1111dbf57ef2e608963a4bffa669884
2026-03-10 00:35:59 -07:00
Marco Wang 53cd9cec15 transformTypeParamBound codemod 9/9 (#55948)
Summary:
X-link: https://github.com/facebook/metro/pull/1665

Pull Request resolved: https://github.com/facebook/react-native/pull/55948

js1 flow-runner codemod flow/transformTypeParamBound --format-files=false xplat/js

Changelog: [Internal]

Reviewed By: SamChou19815

Differential Revision: D95429551

fbshipit-source-id: 6f5694fed74364c6f1c58e28376c86eae6201366
2026-03-05 21:26:42 -08:00
Bartosz Szar ac1aa7588a chore: fix typos in test descriptions and code comments (#55651)
Summary:
I was upgrading bare react native project to expo sdk 54 and stumbled upon
```
"TurboModule system assumes returnType == void iff the method is synchronous."
```
error from `turbomodule/core/TurboModuleInteropUtils.kt`

I thought that `iff` with double `f` was a typo and wanted to submit a pr with fix - I learned that it means `if and only if` - decided to scan the repo for any other typos anywany - submitting the ones that I've found.

## Changelog:
[Internal]
<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

Pull Request resolved: https://github.com/facebook/react-native/pull/55651

Reviewed By: cipolleschi

Differential Revision: D93876470

Pulled By: cortinico

fbshipit-source-id: 43fc905bda14e77b27cdeda568bde1e2299d9d0f
2026-02-23 13:35:53 -08:00
Marco Wang cd3a9c55c1 Transform all remaining utility types (#55178)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55178

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.

drop-conflicts

Command:

`js1 flow-runner codemod flow/transformUtilityType --format-files=false --legacy-type='ALL'`

Reviewed By: SamChou19815

Differential Revision: D90728908

fbshipit-source-id: a8a1a06eb274cc32b12e893679aa92034eb962c4
2026-01-15 16:02:51 -08:00
Alex Hunt f1bedfb92b Bump packages for next release (#55172)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55172

Follows the recent `0.84-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.85.0-main`

Reviewed By: vzaidman

Differential Revision: D90698490

fbshipit-source-id: b81b840bfd66e631f160a11c4c64baa6850e3393
2026-01-14 12:17:16 -08:00
Rob Hogan c9c601d61a Node.js: Drop support for Node.js versions released before 20.19.4, and EOL v21,v23 (#55114)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55114

Our official [docs](https://reactnative.dev/docs/set-up-your-environment#node--watchman) require:

> Node 20.19.4 or newer

Currently, our `package.json#engines` fields express this as `"node": ">= 20.19.4"`

This is a bit imprecise because of Node's overlapping release lines - e.g. v24.0.0 is actually older than v20.19.4 (2025-07-15), and the whole v21 line was already EOL before v20.19.4.

The release *date* is relevant because Node.js frequently backports the most important updates - notably, `require(esm)` is already stable in Node 20.19 but is not unflagged in v22 until v22.12.

This makes the `package.json#engines` requirement truer to the documented requirement, dropping some old minors and EOL majors that prevent us using features included in v20.19.

Notably, `require(esm)` is stable and unflagged on all versions supported from this diff.

 - v21 and v23 are EOL, so are dropped.
 - v22.13 pre-dates 20.19.4 and is the first to have unflagged silent `require(esm)`
 - v24.3.0 pre-dates 20.19.4 and is the first to unflag TS-stripping
 - Support v25 and newer.

Changelog:
[General][Breaking] Drop support for EOL Node.js lines and old minors.

Reviewed By: cortinico, huntie

Differential Revision: D90467358

fbshipit-source-id: a5fdfb1b93a9d6cffe78eb6811ff7420ab906f44
2026-01-14 10:49:05 -08:00
Marco Wang 92c32780f1 Transform $ReadOnlyArray to ReadonlyArray 18/n (#55152)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55152

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.

drop-conflicts

Command:

`js1 flow-runner codemod flow/transformUtilityType --legacy-type='$ReadOnlyArray'`

Reviewed By: SamChou19815

Differential Revision: D90424826

fbshipit-source-id: 207e1abebb50671e8eb2a7f79ecfeaf4569b5b3e
2026-01-13 21:59:05 -08:00
Rob Hogan 0cda10b00a Revert: Bump minimum Node.js version to v22.11 (prev LTS) (#55113)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55113

Reverts https://github.com/facebook/react-native/pull/55038

Dropping v20 (still in LTS) causes friction with Expo's LTS policy, so we're restoring support for v20.19.

Changelog: [General][Added] Revert https://github.com/facebook/react-native/pull/55038

Reviewed By: shwanton

Differential Revision: D90467161

fbshipit-source-id: d876cf7869f11e04058f88239f553704e0706514
2026-01-11 14:30:40 -08:00
Marco Wang 41efc3b588 Transform $ReadOnly to Readonly 38/n (#55067)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/55067

Differential Revision: D90146229

fbshipit-source-id: 62733ba51fd0c318140b7a76b499b1a7ac1f7853
2026-01-06 20:23:03 -08:00
Rob Hogan 8f10b339d4 Breaking: Bump minimum Node.js version to v22.11 (prev LTS) (#55038)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55038

Bump the minimum to Node.js v22.11, which is the previous LTS now that v24 is in LTS. Drop support for Node v20.

https://nodejs.org/en/blog/release/v22.11.0
https://nodejs.org/en/about/previous-releases

Changelog: [General][Breaking] Bump minimum Node.js version to v22.11

Reviewed By: cortinico, huntie

Differential Revision: D90109056

fbshipit-source-id: 178f29d3131f21fccf956decc9ac94365a2bfe53
2026-01-05 06:21:25 -08:00
Riccardo Cipolleschi e6923dd1e1 React 19.2.3 sync int React Native OSS (#54966)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54966

Sync of React 19.2.3 into React Native

See also the template change [here](https://github.com/react-native-community/template/pull/195).

Changelog:
[General][Changed] - Sync React 19.2.3 into React Native

jest_e2e[run_all_tests]
bypass-github-export-checks

Reviewed By: cortinico

Differential Revision: D89719053

fbshipit-source-id: a5f226a3811f3eaafb0a1d7ebf848aa55cb0b524
2025-12-29 08:38:45 -08:00
Marco Wang 894a1f16ef Transform mixed to unknown in xplat/js (#54954)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54954

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.
drop-conflicts

Reviewed By: SamChou19815

Differential Revision: D89581744

fbshipit-source-id: 58a6c246629bbe4fb5c0af447dc002c48e10c342
2025-12-22 12:25:44 -08:00
Alex Hunt a1e534a604 Bump packages for next release (#54452)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54452

Follows the recent `0.83-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.84.0-main`

Reviewed By: cipolleschi

Differential Revision: D86534507

fbshipit-source-id: 47b88dce919857398f41516d03d60259730d2887
2025-11-12 04:22:19 -08:00
Marco Wang f8198f6629 Deploy 0.290.0 to xplat (#54439)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54439

[changelog](https://github.com/facebook/flow/blob/main/Changelog.md)
Changelog: [Internal]

Reviewed By: SamChou19815

Differential Revision: D86443337

fbshipit-source-id: 05014b1ebf240fed8e95f10466503c1d39abf59a
2025-11-06 18:23:12 -08:00
Riccardo Cipolleschi 6f482708b5 Sync React 19.2 into React Native (#54109)
Summary:
X-link: https://github.com/facebook/metro/pull/1598

Pull Request resolved: https://github.com/facebook/react-native/pull/54109

This change syncs React 19.2 into React native.

bypass-github-export-checks
## Changelog
[General][Changed] - Bump React version to 19.2

Reviewed By: cortinico

Differential Revision: D84282848

fbshipit-source-id: 8bc57be1f39a913c284fb782883ce91fae6750fc
2025-10-10 11:44:06 -07:00
Nicola Corti d9a582e949 Bump packages to 0.83.0-main (#54009)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54009

Packages haven't been bumped on main ahead of 0.83. This takes care of it.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi, huntie

Differential Revision: D83580515

fbshipit-source-id: 7471e77f74e3fb3b4ee6538a49369b5df1393098
2025-10-01 07:13:33 -07:00
Sam Zhou 5c369aa34c Add annotations to fix future natural inference errors in xplat/js: 6/n (#53894)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53894

Changelog: [Internal]

Reviewed By: marcoww6

Differential Revision: D83000736

fbshipit-source-id: 3ba5c59d9b2f7b967c0dccd24a73056430153bdc
2025-09-22 21:55:34 -07:00