Skip to content

[0.81][iOS] Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative#56842

Open
cipolleschi wants to merge 3070 commits into
0.81-stablefrom
cipolleschi/shared-cache-prebuilt-binaries
Open

[0.81][iOS] Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative#56842
cipolleschi wants to merge 3070 commits into
0.81-stablefrom
cipolleschi/shared-cache-prebuilt-binaries

Conversation

@cipolleschi
Copy link
Copy Markdown
Contributor

Adds a shared cache layer at
~/Library/Caches/ReactNative/ for prebuilt iOS tarballs
(Hermes, ReactNativeDependencies, ReactNativeCore).

  • On first download, tarballs are saved to both the local
    Pods artifacts dir and the shared cache.
  • On subsequent pod install runs, if the local Pods
    cache is empty but the shared cache has the tarball for
    that version, it is copied locally instead of
    re-downloaded from Maven.
  • Adds descriptive log messages for each scenario: local
    Pods hit, shared cache hit, and cache miss (download).

This avoids redundant downloads when:

  • The Pods directory is deleted between installs
  • Multiple projects use the same React Native version
  • CI environments have a persistent home directory

Changelog:

[IOS] [CHANGED] - Cache prebuilt iOS binaries (Hermes,
ReactNativeDependencies, ReactNativeCore) in
~/Library/Caches/ReactNative to avoid redundant downloads
across pod installs

Test Plan:

Cold start ==> Downloading

[ReactNativeDependencies] Setting up ReactNativeDependencies...
[ReactNativeDependencies] Building from source: false
[ReactNativeDependencies] Using release tarball
[ReactNativeDependencies] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
[ReactNativeDependencies] Cache miss: downloading reactnative-dependencies-0.81.6-debug.tar.gz from https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:-  0     0    0     0    0     0      0      0 --:--:-- --:- 35 18.3M   35 6580k    0     0  6386k      0  0:00:02  0:0 73 18.3M   73 13.5M    0     0  6827k      0  0:00:02  0:0100 18.3M  100 18.3M    0     0  6915k      0  0:00:02  0:00:02 --:--:-- 6914k
[ReactNativeDependencies] Saved reactnative-dependencies-0.81.6-debug.tar.gz to shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeDependencies] Cache miss: downloading reactnative-dependencies-0.81.6-release.tar.gz from https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-release.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:-  0     0    0     0    0     0      0      0 --:--:-- --:- 67  9.9M   67 6948k    0     0  6332k      0  0:00:01  0:0100  9.9M  100  9.9M    0     0  6607k      0  0:00:01  0:00:01 --:--:-- 6603k
[ReactNativeDependencies] Saved reactnative-dependencies-0.81.6-release.tar.gz to shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeDependencies] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz"}
[ReactNativeCore] Setting up ReactNativeCore...
[ReactNativeCore] Building from source: false
[ReactNativeCore] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz
[ReactNativeCore] Cache miss: downloading reactnative-core-0.81.6-debug.tar.gz from https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:-  1 78.5M    1 1557k    0     0  5035k      0  0:00:15 --:- 10 78.5M   10 8537k    0     0  6536k      0  0:00:12  0:0 19 78.5M   19 15.4M    0     0  6866k      0  0:00:11  0:0 28 78.5M   28 22.5M    0     0  6990k      0  0:00:11  0:0 37 78.5M   37 29.7M    0     0  7062k      0  0:00:11  0:0 46 78.5M   46 36.4M    0     0  7037k      0  0:00:11  0:0 55 78.5M   55 43.5M    0     0  7065k      0  0:00:11  0:0 64 78.5M   64 50.5M    0     0  7077k      0  0:00:11  0:0100 78.5M  100 78.5M    0     0  6852k      0  0:00:11  0:00:11 --:--:-- 6482k
[ReactNativeCore] Saved reactnative-core-0.81.6-debug.tar.gz to shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeCore] Cache miss: downloading reactnative-core-0.81.6-release.tar.gz from https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-release.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 26.3M  100 26.3M    0     0  5683k      0  0:00:04  0:00:04 --:--:-- 5793k
[ReactNativeCore] Saved reactnative-core-0.81.6-release.tar.gz to shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeCore] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz"}
Configuring the target with the New Architecture
[ReactNativeCore] Using React Native Core and React Native Dependencies prebuilt versions.
[Codegen] Analyzing /Users/cipolleschi/Tests/My0_81App/package.json

Warn shared cache, Empty Pods dir ==> Copy

[ReactNativeDependencies] Setting up ReactNativeDependencies...
[ReactNativeDependencies] Building from source: false
[ReactNativeDependencies] Using release tarball
[ReactNativeDependencies] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
[ReactNativeDependencies] Cache hit: copying reactnative-dependencies-0.81.6-debug.tar.gz from shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeDependencies] Cache hit: copying reactnative-dependencies-0.81.6-release.tar.gz from shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeDependencies] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz"}
[ReactNativeCore] Setting up ReactNativeCore...
[ReactNativeCore] Building from source: false
[ReactNativeCore] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz
[ReactNativeCore] Cache hit: copying reactnative-core-0.81.6-debug.tar.gz from shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeCore] Cache hit: copying reactnative-core-0.81.6-release.tar.gz from shared cache (/Users/cipolleschi/Library/Caches/ReactNative)
[ReactNativeCore] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz"}
Configuring the target with the New Architecture
[ReactNativeCore] Using React Native Core and React Native Dependencies prebuilt versions.
[Codegen] Analyzing /Users/cipolleschi/Tests/My0_81App/package.json
...
[ReactNativeDependencies] Using release tarball
[ReactNativeDependencies] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-debug.tar.gz already exists in Pods. Skipping download.
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-release.tar.gz already exists in Pods. Skipping download.

Warm Cache, Pods folder populated ==> Nothing happens

[ReactNativeDependencies] Setting up ReactNativeDependencies...
[ReactNativeDependencies] Building from source: false
[ReactNativeDependencies] Using release tarball
[ReactNativeDependencies] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-debug.tar.gz already exists in Pods. Skipping download.
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-release.tar.gz already exists in Pods. Skipping download.
[ReactNativeDependencies] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz"}
[ReactNativeCore] Setting up ReactNativeCore...
[ReactNativeCore] Building from source: false
[ReactNativeCore] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz
[ReactNativeCore] Tarball reactnative-core-0.81.6-debug.tar.gz already exists in Pods. Skipping download.
[ReactNativeCore] Tarball reactnative-core-0.81.6-release.tar.gz already exists in Pods. Skipping download.
[ReactNativeCore] Source: {http: "https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-core-debug.tar.gz"}
Configuring the target with the New Architecture
[ReactNativeCore] Using React Native Core and React Native Dependencies prebuilt versions.
[Codegen] Analyzing /Users/cipolleschi/Tests/My0_81App/package.json
[Codegen] Searching for codegen-enabled libraries in the app.
[Codegen] The "codegenConfig" field is not defined in package.json. Assuming there is nothing to generate at the app level.
[Codegen] Searching for codegen-enabled libraries in react-native.config.js
[Codegen] Found react-native-safe-area-context
[Codegen] Processing safeareacontext
[Codegen] Searching for podspec in the project dependencies.
[Codegen] Supported Apple platforms: ios, macos, tvos, visionos for safeareacontext
[Codegen] Generating Native Code for safeareacontext - ios
[Codegen] Generated artifacts: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios
[Codegen] Generating RCTThirdPartyComponentsProvider.h
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTThirdPartyComponentsProvider.h
[Codegen] Generating RCTThirdPartyComponentsProvider.mm
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTThirdPartyComponentsProvider.mm
[Codegen] Generating RCTModulesProvider.h
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTModuleProviders.h
[Codegen] Generating RCTModuleProviders.mm
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTModuleProviders.mm
[Codegen] Generating RCTAppDependencyProvider
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTAppDependencyProvider.h
[Codegen] Generated artifact: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/RCTAppDependencyProvider.mm
[Codegen] Generated podspec: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/ReactAppDependencyProvider.podspec
[Codegen] Generated podspec: /Users/cipolleschi/Tests/My0_81App/ios/build/generated/ios/ReactCodegen.podspec
[Codegen] Done.
[ReactNativeDependencies] Using release tarball
[ReactNativeDependencies] Using tarball from URL: https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.6/react-native-artifacts-0.81.6-reactnative-dependencies-debug.tar.gz
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-debug.tar.gz already exists in Pods. Skipping download.
[ReactNativeDependencies] Tarball reactnative-dependencies-0.81.6-release.tar.gz already exists in Pods. Skipping download.
Analyzing dependencies

zeyap and others added 30 commits April 16, 2026 08:53
…ion complete callback (#56459)

Summary:
Pull Request resolved: #56459

## Changelog:

[Internal] [Added] - Allow waiting for user land Animated animations before firing transition complete callback

Instead of calling `onCompleteCallback` synchronously at the end of `startViewTransition`, defer it until all animations have finished. Since transition animation can be kicked off in user land from view transition event handlers, we need extra APIs to signal to native side when animation starts and finishes. This ensures the transition lifecycle properly waits for native animated transitions to complete.

- Add `waitForTransitionAnimation` / `transitionAnimationFinished` to the delegate interface and expose via `NativeViewTransition` TurboModule
- JS calls `waitForTransitionAnimation(animationId)` before starting each animation and `transitionAnimationFinished(animationId)` in the completion callback
- `ViewTransitionModule` tracks pending animation IDs in a `std::set` and fires `onCompleteCallback_` only when all animations are done
   - only track and wait for animations started during transition-ready callback
- if no animation requests to be waited for, resolve complete promise immediately when transition-ready callback finishes

Reviewed By: sammy-SC

Differential Revision: D99366980

fbshipit-source-id: 6313bdd2b3f7b90a5aee24e0faec905bce75d715
Summary:
On Android 15 (API 35), edge-to-edge is enforced by default unless the app explicitly opts out via `windowOptOutEdgeToEdgeEnforcement`. On Android 16+, it's always enforced regardless.

Previously, edge-to-edge behavior was only driven by the `edgeToEdgeEnabled` gradle property, meaning apps on Android 15+ could be in edge-to-edge mode without React Native being aware of it, leading to incorrect insets / layout behavior.

This PR introduces `isEdgeToEdge`, a computed value that accounts for the OS-level enforcement in addition to the gradle flag, and replaces most usages of `isEdgeToEdgeFeatureFlagOn` with it. A new `initEdgeToEdge(context, flag)` function replaces `setEdgeToEdgeFeatureFlagOn()` and reads the theme attribute to detect opt-out on API 35.

## Changelog:

[ANDROID] [FIXED] - Handle edge-to-edge when it's not enabled by the `edgeToEdgeEnabled` gradle property but enforced by the OS (Android 15+)

Pull Request resolved: #56055

Test Plan:
- Verify on Android 15 device/emulator **without** `edgeToEdgeEnabled = true`: `isEdgeToEdge` should be `true` (unless opted out via theme attribute).
- Verify on Android 16+ device/emulator: `isEdgeToEdge` should always be `true`.
- Verify on Android 14 and below without the flag: `isEdgeToEdge` should be `false`.
- Verify with `edgeToEdgeEnabled = true`: behavior unchanged, `isEdgeToEdge` is `true` on all API levels.

Reviewed By: javache

Differential Revision: D100437440

fbshipit-source-id: 7cc826ccd2d1596121671eb456358f558e14299c
Summary:
`Modal` accepts a `style` prop via `ViewProps` (since `ModalProps` spreads `...ViewProps`) but silently discards it. The inner container `<View>` only applies `styles.container` and `containerStyles` (which handles `backdropColor`/`transparent`), so any style passed by the consumer has no effect.

For example, `<Modal style={{ padding: 20 }}>` compiles without errors but the padding is never applied.

This PR forwards `this.props.style` to the inner container View with a carefully designed precedence chain:

```
styles.container (layout defaults + white background)
  → this.props.style (consumer overrides)
    → containerStyles (explicit transparent / backdropColor always win)
```

`containerStyles` now only sets `backgroundColor` when `transparent` or `backdropColor` are explicitly passed, ensuring these Modal-specific API props always take precedence over the generic `style` prop while still allowing consumers to customize other style properties.

**Precedence examples:**
| Usage | Result |
|---|---|
| `<Modal style={{ backgroundColor: 'red' }}>` | Red (user overrides default white) |
| `<Modal transparent>` | Transparent (explicit prop wins) |
| `<Modal transparent style={{ backgroundColor: 'red' }}>` | Transparent wins |
| `<Modal backdropColor="blue" style={{ backgroundColor: 'red' }}>` | Blue wins |
| `<Modal style={{ padding: 20 }}>` | Works, no conflicts |

## Changelog:

[GENERAL] [FIXED] - Forward `style` prop to Modal's inner container View with correct precedence so consumer styles are applied without overriding `transparent` or `backdropColor`

Pull Request resolved: #56181

Test Plan:
1. Render a Modal with a custom style prop:

   ```jsx
   <Modal visible style={{ padding: 40, backgroundColor: 'red' }}>
     <View style={{ flex: 1, backgroundColor: 'white' }}>
       <Text>Hello</Text>
     </View>
   </Modal>
   ```

2. **Before fix:** `padding` and `backgroundColor` are silently ignored
3. **After fix:** The modal container has 40px padding and a red background

Also verified that:
- `transparent={true}` always produces a transparent background, even if `style={{ backgroundColor }}` is set
- `backdropColor` always takes precedence over `style.backgroundColor`
- Default behavior (no `style` prop) is unchanged — white background
- Non-backgroundColor style properties (padding, margin, etc.) work without conflicts

Reviewed By: javache

Differential Revision: D101170804

Pulled By: zeyap

fbshipit-source-id: b138648ce41b55eb794c79a0217f905d5cc9a5f2
Summary:
This PR introduces a `ExtraWindowEventListener` interface that allows native modules to be notified when new windows are created or destroyed (e.g. Modal dialogs).

Third-party libraries can implement it, or emit window events through `ReactContext.onExtraWindowCreate` / `ReactContext.onExtraWindowDestroy`.

This opens the door for libraries like `expo-navigation-bar` to build a proper `NavigationBar` module that stays in sync across all windows (including modals).

## Related issue

- zoontek/react-native-navigation-bar#4

## Changelog:

[ANDROID] [ADDED] - Add `ExtraWindowEventListener` interface to allow native modules to react to window creation / destruction (e.g. Modal dialogs)

Pull Request resolved: #55721

Test Plan: Follow #56059 test plan

Reviewed By: cortinico

Differential Revision: D94871845

Pulled By: alanleedev

fbshipit-source-id: b2c00950c3c60dbeb3d53520d95160b301829a5e
Summary:
## Changelog:

[Internal] [Fixed] - unbreak ViewTransition fantom tests

this gets broken after my recent changes to viewtransition runtime

Reviewed By: NickGerleman

Differential Revision: D101224031

fbshipit-source-id: ecef6d4ea73635a6416a1febf9c44b9ecfef0f22
#55855)

Summary:
`KeyboardAvoidingView` has several issues on Android 15+ and when `edgeToEdgeEnabled` is set to `true` on Android < 15:

1. **Keyboard events relied on a legacy detection path for Android < 30** (`checkForKeyboardEventsLegacy`), which used height heuristics (`heightDiff > mMinKeyboardHeightDetected`) to guess whether the keyboard was visible.
2. **`keyboardDidHide` reported incorrect `screenY` values.** It used `mVisibleViewArea.height()`, which in edge-to-edge mode doesn't correspond to the actual screen bottom.
3. **`KeyboardAvoidingView` used `_onKeyboardChange` for `keyboardDidHide` on Android**, which stores the event instead of nullifying it. After keyboard dismissal, any subsequent `onLayout` would re-enter `_updateBottomIfNecessary` with stale coordinates, causing a render loop (especially visible with `behavior="height"` in edge-to-edge mode, where `frame.y` shifts slightly on each layout cycle).

This PR:

- Removes `checkForKeyboardEventsLegacy` and uses `WindowInsetsCompat` APIs (via AndroidX)
- Fixes `keyboardDidHide` to report `screenY` as `mVisibleViewArea.bottom + barInsets.bottom`
- Fixes the Android `keyboardDidHide` listener in `KeyboardAvoidingView` to use `_onKeyboardHide`, matching the iOS behavior and breaking the render loop.

Closes #49759

## Changelog:

[ANDROID] [FIXED] - Fix `KeyboardAvoidingView` on Android 15+ / with `edgeToEdgeEnabled`

Pull Request resolved: #55855

Test Plan:
Tested with `rn-tester` KeyboardAvoidingView example on:
- Android 16 (API 36) (edge-to-edge is enforced)
- Android 14 (API 34) with `edgeToEdgeEnabled` set to `true` or `false`
- Android 7 (API 24) with `edgeToEdgeEnabled` set to `true` or `false`

For each, verified:
- `behavior="padding"`: keyboard open/close adjusts padding correctly
- `behavior="position"`: keyboard open/close translates content correctly
- `behavior="height"`: keyboard open/close works without render loop or glitching
- `keyboardDidShow` and `keyboardDidHide` events report correct coordinates

Reviewed By: mdvacca

Differential Revision: D100437445

Pulled By: alanleedev

fbshipit-source-id: 23b89a4380d02a0f524d587f89d023d21782406c
…e possible (#56465)

Summary:
Pull Request resolved: #56465

The `cloneProps` function in `AnimationBackend.cpp` was using `std::move(*animatedProps.rawProps)` inside a `shadowTree.commit()` transaction lambda. Since commits can be retried (when `currentRevision_.number != oldRevision.number`), the moved-from `RawProps` would be in an unspecified state on the second attempt, leading to incorrect or undefined behavior.

When `enableFabricCommitBranching` is enabled, commit retries are not a concern, so moving is safe. When disabled, we now copy via `RawProps(*animatedProps.rawProps)` instead.

This is the only dangerous move in the animation backend commit path. The `AnimationBackendCommitHook` already copies correctly (`RawProps(*snapshot->rawProps)`), and `AnimatedPropsRegistry::getMap()` is safe because moved pending data persists in the `map` member across retries.

Changelog: [General][Fixed] - Fix potential data corruption in animation backend when ShadowTree commits are retried by copying RawProps instead of moving them

Reviewed By: zeyap

Differential Revision: D101161363

fbshipit-source-id: 43b9277f37563098c8ba878777d7a3099bdf1373
Summary:
Pull Request resolved: #56482

Changelog: [internal]

`ReactNativeType` is the type of the legacy renderer, which is being removed. This removes the references to it so the removal can land without Flow errors.

Reviewed By: zeyap

Differential Revision: D101352959

fbshipit-source-id: 3425260a1604eb83998b32dd8c25d399eb6c6ee1
…ow (#36297) (#56483)

Summary:
Pull Request resolved: #56483

## Summary

PR #36285 deleted the Paper (legacy) renderer, including the shim file
`scripts/rollup/shims/react-native/ReactNative.js`. However, the
`runtime_commit_artifacts` workflow still tries to `rm` this file after
moving build artifacts into `compiled-rn/`. Since the file no longer
exists in the build output, `rm` (without `-f`) fails and kills the
entire step.

This has caused **every run of the Commit Artifacts workflow to fail
since #36285 landed on April 16**, blocking both `builds/facebook-www`
and `builds/facebook-fbsource` branches from receiving new build
artifacts. This in turn blocks DiffTrain from syncing React changes into
Meta's internal monorepo.

DiffTrain build for [bf45a68dd35ed08860b6a70fed641dfe6d7d290d](facebook/react@bf45a68)

Reviewed By: zeyap

Differential Revision: D101329586

fbshipit-source-id: d38877d5cc964c46257cb73678f80d0a7c729d90
…ce node (#56479)

Summary:
Pull Request resolved: #56479

## Changelog:

[General] [Fixed] - support multiple old pseudo elements for same name but different source node

We will need to track multiple old pseudo elements for same name but different source node when doing a series of shared transitions:
1. go from component A to component B (A stays hidden with Activity but not unmounted)
2. go back to A (B unmounted)
3. hide A and show B again

A will lose its old pseudo element node, because at #1, B's old pseudo element node overrides A's (since they have the same vt name), and at #2, B's old node gets cleaned up. At #3, since createViewTransitionInstance won't be called for A again (react reconciler assumes the instance is only created once until a component is unmounted), there's no valid old node for A anymore.

Reviewed By: sammy-SC

Differential Revision: D101237889

fbshipit-source-id: 4f670877e3786f0aa89409c1fd5b9784515bd2c2
Summary:
Pull Request resolved: #56474

On Android, pressing the hardware back button while LogBox notification toasts or the full inspector overlay are visible has no effect on the JS side. The only way to dismiss notifications is the on-screen X button, and the only way to close the inspector is via Minimize/Dismiss.

This adds `BackHandler` listeners to both JS containers:

**Notification toasts**: A new `LogBoxNotificationBackHandler` component mounts alongside the toasts and registers a `hardwareBackPress` listener that calls `clearWarnings()` + `clearErrors()`, equivalent to pressing X on every visible toast. The component returns null and auto-cleans the listener on unmount.

**Inspector overlay**: `LogBoxInspectorContainer` registers a `hardwareBackPress` listener in `componentDidMount` that calls `_handleMinimize()` (`setSelectedLog(-1)`), closing the overlay non-destructively — same as pressing the Minimize button.

Changelog: [Android][Added] - Allow LogBox notification toasts and inspector overlay to be dismissed via Android back button

Reviewed By: alanleedev

Differential Revision: D101178179

fbshipit-source-id: c2100d2cc494c326d8a91caa906faabb3d23381c
Summary:
Pull Request resolved: #56478

Changelog: [General] [Fixed] - Respect enum values for TurboModule c++ codegen

Defining an enum like this:

```js
export enum CustomPropertyEditor {
  BitMask = 0,
  Entity = 1,
  Slider = 2,
  AudioEvent = 3,
  CollisionLayer = 4,
  MaterialComponentDeprecatedProperty = 5,
  MeshMaterialList = 6,
  Submesh = 7,
  // CoreUiLayout (8) removed — rendered identically to ClassOrList
  MaterialMapJson = 9,
  AnimationTable = 10,
  SkeletonAsset = 11,
  NavMeshAreaType = 12,
  VFXAsset = 13,
  Table = 14,
  VariableTable = 15,
  AudioBus = 16,
  LodSettings = 17,
  WorldSearch = 18,
  EntityMaterialList = 19,
  NpcId = 20,
  LightingModelVersion = 21,
  PlatformSelector = 22,
  ComponentReference = 23,
}
```
(notice number 8 ), will cause the generated enum to actually look like:
```
  enum class NativeEditableObjectModuleCustomPropertyEditor {
    BitMask, Entity, Slider, AudioEvent, CollisionLayer,
    MaterialComponentDeprecatedProperty, MeshMaterialList, Submesh,
    MaterialMapJson, AnimationTable, ...
  };
```

in other words, the values don't match up after the core ui value. This is quite dangerous and I'm surprised no one has ever noticed that

This diff fixes things such that if an integer value is explicitly assigned, the value is preserved in the generated enum.

Reviewed By: christophpurrer

Differential Revision: D101229471

fbshipit-source-id: 366ea2d16ac74e112f1b68c5ad3d0877dedb918c
…gWarn (#56494)

Summary:
Pull Request resolved: #56494

Changelog: [Internal]

## Problem

`RCTSyncImageManager` (used exclusively in test environments) calls `RCTLogError` when a network image fails to load within 20 seconds. On iOS, `RCTLogError` triggers a **native redbox** — a full-screen red overlay that:

1. **Covers the entire app UI**, making all elements invisible to E2E test assertions
2. **Cannot be dismissed on iOS** — `NativeExceptionsManager.dismissRedbox()` is a no-op (empty method in `RCTExceptionsManager.mm`)
3. **Cannot be suppressed by JavaScript-side mechanisms** — `LogBox.ignoreAllLogs()` and `suppress_warning` mobile config only affect JS-level LogBox, not native `RCTLogError` redboxes
4. **Instantly fails any E2E test** at the next `toBeVisible()` / `toHaveText()` assertion because the redbox overlay blocks all UI elements

This causes **~2-5% infrastructure flakiness** across all iOS E2E tests that render components with network images (e.g., recommendation cards, ad previews, profile images), due to transient image load timeouts in the CI test sandbox.

### Error Flow
```
Image URL request in test sandbox
  → Network timeout (sandbox cant fetch from lookaside.facebook.com)
    → RCTSyncImageManager.mm dispatch_group_wait expires (20s)
      → RCTLogError(@"Image timed out in test environment for url: %@")
        → RCTLog.mm: level >= RCTLOG_REDBOX_LEVEL
          → Native RedBox overlay shown (full-screen, undismissable on iOS)
            → All toBeVisible() assertions fail
              → Test marked as FAILED
```

Differential Revision: D101052445

fbshipit-source-id: f615ac48ca210c5b070798f95ab2675ab9449e70
Summary:
Pull Request resolved: #56472

Fix clang-diagnostic-unused-parameter warnings by commenting out the unused 'context' parameter in two fromRawValue functions. This maintains API compatibility while resolving the lint warnings.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D101108449

fbshipit-source-id: 34da8573326c1ebc11dad01104f8857a21c0adc5
Summary:
Pull Request resolved: #56495

UIManagerBinding::dispatchEvent checks for an existing timeStamp property before injecting one, but only checks the camelCase variant. Native events that use lowercase timestamp (e.g. pointer events) would have a duplicate timeStamp injected with the current time, which then takes precedence in the SyntheticEvent timestamp resolution chain (event.timeStamp || event.timestamp).

This adds a check for both timeStamp and timestamp before auto-injecting, preserving the original native event timestamp when present in either casing.

Root cause: #55878 only checked for timeStamp (camelCase).

Changelog: [General][Fixed] - Fix event timestamp injection overriding native timestamps with lowercase property name

Reviewed By: mdvacca

Differential Revision: D101522871

fbshipit-source-id: 74d91a3958ac73927251189f07f954303d45688e
…#56497)

Summary:
Pull Request resolved: #56497

Reorder the fields to match the struct declaration order:
text, selectionRange, contentSize, contentOffset, contentInset, eventCount,
layoutMeasurement, zoomScale.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D101560071

fbshipit-source-id: 462db623b62ed2cf01481c9406a8c750ff1268bc
Summary:
Pull Request resolved: #56501

Add an early NPM token validation step to the create-release workflow.
This runs `npm whoami` right after checkout to fail fast if the token is
expired or invalid, avoiding wasted CI time on a release that would fail
at the publish step.

The step gracefully skips when no token is present (e.g. fork PRs).

## Changelog:
[Internal] -

Reviewed By: christophpurrer

Differential Revision: D101377190

fbshipit-source-id: 53243a24649f86d274b2ea31793333fd815e69cb
Summary:
Pull Request resolved: #56502

Adds an NPM token validation step to the `build_npm_package` job of the
React Native nightly workflow. Mirrors the same check we recently added
to `create-release.yml` and the Hermes `rn-build-hermes.yml` workflows
so we fail fast (with a clear message) instead of failing partway
through the publish step when the token is expired or missing.

## Changelog:
[Internal] -

Reviewed By: fabriziocucci

Differential Revision: D101594276

fbshipit-source-id: bb0fbddf5eba921f4184117dc29c7cc9e911a00e
Summary:
Pull Request resolved: #56503

Changelog: [Internal]

Changes the signals pointing out C++ api snapshot not being updated to be blocking.

Commits the new baseline snapshots

Reviewed By: cipolleschi, cortinico

Differential Revision: D101617655

fbshipit-source-id: 8836cb55292ab2e3fa0b696d289f9bd0daf46dec
Summary:
Pull Request resolved: #56485

## Changelog:

[Internal] [Fixed] - Clear AnimatedPropsRegistry on surface stop

When `useSharedAnimatedBackend` is enabled, the `AnimatedPropsRegistry` accumulates
`SurfaceContext` entries (containing `shared_ptr<ShadowNodeFamily>` and `PropsSnapshot`
data) for each surface that has animated views. These entries are never cleaned up when
a surface is destroyed via `UIManager::stopSurface()`, because that method only calls
the legacy `stopSurfaceForAnimationDelegate()` — the shared backend's registry is untouched.

We also see increased `RetryableMountingLayerException` errors in production which stack trace
shows there are mount items committing to surface that no longer exists.

This change:
1. Adds `animationBackend_->clearRegistry(surfaceId)` to `UIManager::stopSurface()`
2. Changes `AnimatedPropsRegistry::clear()` to fully erase the `surfaceContexts_` map
   entry instead of just clearing its contents

Reviewed By: christophpurrer

Differential Revision: D101354994

fbshipit-source-id: c7668f728050a0d3f5c09ad5ca51e48450c1b87e
Summary:
Pull Request resolved: #56511

## Changelog:

[Internal] [Fixed] - Fix react-native-cxx-stable-api-snapshot-validation test

Reviewed By: jeffrey-beauchamp

Differential Revision: D101646907

fbshipit-source-id: 6fda6032ee3a9b1c418ea19c7fffd5aabe614fb2
Summary:
Pull Request resolved: #56488

Fixed clang-diagnostic-unused-parameter warnings in IMountingManager.h by commenting out parameter names while preserving types. This maintains API compatibility for virtual methods while eliminating lint warnings.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D101110289

fbshipit-source-id: ee9bf593b648c6db8e0764613b29e47036fd7df8
Summary:
Pull Request resolved: #56506

React Native's `PerformanceObserver` previously defaulted `durationThreshold` to 0 for `event` entries, while the W3C Event Timing spec
(https://www.w3.org/TR/event-timing/#sec-modifications-perf-timeline) mandates a default of 104ms. The previous default flooded observers with short events
(clicks, pointer up/down) that are not interesting for responsiveness
measurement.

This change brings React Native in line with the spec by making 104ms the
default. The default is applied at the JSI bridge boundary in
`NativePerformance.cpp` (the JS API boundary on the C++ side) when JS does not
provide an explicit `durationThreshold`. The C++ public observer API
(`PerformanceObserverObserveSingleOptions::durationThreshold`) and the global
event buffer (`eventBuffer_.durationThreshold`) keep their `HighResDuration::zero()`
default — applying 104ms to the global buffer would drop sub-104ms events at
the source, breaking observers that explicitly request `durationThreshold: 0`.

Changes in `react-native`:
- `NativePerformance.cpp`: apply 104ms default at the JSI bridge boundary.
- `PerformanceApiExample.js` (rn-tester): pass `durationThreshold: 0` to
  preserve previous behavior.
- `EventTimingAPI-itest.js`: migrate 4 existing call sites to
  `{type: 'event', durationThreshold: 0}` and add a new test verifying the
  104ms default.

Sites using `{entryTypes: ['event']}` were converted to
`{type: 'event', durationThreshold: 0}` since the spec (and existing JS
validation in `PerformanceObserver.js`) disallows `durationThreshold` together
with `entryTypes`.

Changelog: [General][Fixed] - PerformanceObserver: `observe({type: 'event'})` now correctly defaults `durationThreshold` to 104ms per the W3C Event Timing spec instead of reporting all events.

Reviewed By: hoxyq

Differential Revision: D101629586

fbshipit-source-id: 897914e8582a3d16db9e9388606be5d0aebd19ab
Summary:
Pull Request resolved: #56514

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D101652820

fbshipit-source-id: f7608fbf92a8fd2928434e74ad03bfc01b318d20
…r-modern (#56496)

Summary:
Pull Request resolved: #56496

Add a guard in the `Tracing.end` CDP handler to check `sessionState_.hasPendingTraceRecording` before calling `stopTracing()`. This prevents a null-pointer crash (SIGSEGV) in `HostTargetTraceRecording::stop()` when `Tracing.end` is sent after `Tracing.start` was rejected (e.g. due to multiple registered host targets in the global inspector singleton).

The guard matches the existing pattern in `TracingAgent::~TracingAgent()` (line 29). When tracing was never started, it now returns an `InvalidRequest` error instead of crashing.

Changelog: [Internal]

Reviewed By: huntie

Differential Revision: D101557975

fbshipit-source-id: 3ab754b9421b3bee3e3bde99ce012007d5a10368
Summary:
Pull Request resolved: #56493

Fixed clang-diagnostic-unused-parameter warnings in EventQueueProcessorTest.cpp by removing unused parameter names from lambda functions.

Changes:
- Line 51: Removed parameter name 'runtime' from dummyEventPipeConclusion lambda
- Line 52: Removed parameter name 'stateUpdate' from dummyStatePipe lambda

This is a standard C++ practice for handling unused parameters - keeping the type for API compatibility while removing the name to silence the warning.

Changelog: [Internal]

Reviewed By: zeyap

Differential Revision: D101110552

fbshipit-source-id: 3391080dcaa4c865177e164869b9732952cde906
Summary:
Pull Request resolved: #56516

Fixed clang-diagnostic-unused-parameter warnings in TimerManager.cpp by commenting out the unused 'runtime' parameter names in two functions:
- deleteTimer() at line 135
- deleteRecurringTimer() at line 152-153

Both functions accept a jsi::Runtime& parameter for API compatibility but don't use it internally. The fix maintains the function signatures while suppressing the warnings by commenting out the parameter names.

Changelog: [Internal]

Reviewed By: zeyap

Differential Revision: D101108602

fbshipit-source-id: 95554385c6d36e724fdc1de4a3b20e1e1014a39c
Summary:
Pull Request resolved: #56489

C++ enums cannot have float values - they must be int or long. This removes the invalid FloatEnum example (with values 0.0, 0.1, 0.2) from the react-native-codegen test fixtures and the corresponding enumFloat parameter reference. All affected test snapshots have been regenerated.

Changelog: [Internal]

Reviewed By: shwanton

Differential Revision: D101433764

fbshipit-source-id: eff21d3fa9c48ab11dfb8ef861ac0b8122ff5602
Summary:
Pull Request resolved: #56518

The fix adds null-coalescing fallbacks (`?: ""`) for UTF8String calls that return `const char * _Nullable` but are passed to `std::string` constructors or C++ functions expecting `const char * _Nonnull`.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D101668743

fbshipit-source-id: 80920f25317b0c258387f4b2701b35afe20e3896
Summary:
Add Changelog for 0.85.2

## Changelog:
[Internal] - Add Changelog for 0.85.2

Pull Request resolved: #56515

Test Plan: N/A

Reviewed By: christophpurrer

Differential Revision: D101668302

Pulled By: cipolleschi

fbshipit-source-id: 1c3e4c6e7751fe35ab8c2af31181ad53d43dc8fe
cortinico and others added 18 commits May 12, 2026 18:22
Summary:
X-link: facebook/yoga#1944

Pull Request resolved: #56784

Migrate YogaUnit.java to YogaUnit.kt by adding Unit to KOTLIN_ENUM_NAMES in enums.py and regenerating.

Reviewed By: fabriziocucci

Differential Revision: D104666347

fbshipit-source-id: 99f58b2d1cbea1592a3f4d1aa2608d42ba17e095
Summary:
X-link: facebook/yoga#1949

Pull Request resolved: #56793

Migrate YogaWrap.java to YogaWrap.kt by adding Wrap to KOTLIN_ENUM_NAMES in enums.py and regenerating. All enums are now migrated to Kotlin — KOTLIN_ENUM_NAMES now contains all enum names.

Reviewed By: fabriziocucci

Differential Revision: D104666339

fbshipit-source-id: c30cac3d1f8cd5d8ac863c961ad7c90f4371cc58
Summary:
Pull Request resolved: #56810

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

Reviewed By: panagosg7

Differential Revision: D105015188

fbshipit-source-id: e224f3112fa1c4b707fb1485c9474df5c5f6e53a
…ks (#56803)

Summary:
Two developers (or one developer on two paths, or CI vs. local) running pod install on the same React Native project at the same commit get different SPEC CHECKSUMS entries for React-Core-prebuilt and ReactNativeDependencies in Podfile.lock. That breaks pod install-deployment style verification and any workflow that expects Podfile.lock to be reproducible.

CocoaPods derives each SPEC CHECKSUMS entry by hashing the in-memory podspec JSON. So anything embedded in source.http, prepare_command, user_target_xcconfig, etc. becomes part of the hash. Two podspec-resolution sites in this repo build their source.http from an absolute on-disk path.

Because project_pods_root is an absolute path, the resulting file://<abs>/... URL differs across machines or working-tree paths, so the hashed JSON differs, so the checksum differs.

### How

The Maven URL for each tarball is already computed inside both functions (stable_tarball_url(...) / nightly_tarball_url(...) / release_tarball_url(...)). Returning that URL — a stable string identical across machines — instead of the local file:// URL makes source.http path-free. CocoaPods downloads from Maven and caches the tarball itself, so functionality is preserved.

The pre-existing local-tarball download is kept untouched (its only remaining consumer is the opt-in  `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1` dSYM-injection path in rncore.rb, which still needs file:// to feed CocoaPods a mutated tarball — gated by unless @download_dsyms so the leak is preserved only for that flag).

**Out of scope: **

hermes-engine.podspec has the same shape of leak in user_target_xcconfig.HERMES_CLI_PATH. Fixing it requires a paired change to ensure hermesc lands at the new ${PODS_ROOT}-relative path; that's a separate PR.

## Changelog:

[IOS] [FIXED] - Fix Pod install checksum drifting

Pull Request resolved: #56803

Test Plan:
Run `pod install` and verify that none of the following files contains absolute paths:

- Pods/Local Podspecs/React-Core-prebuilt.podspec.json
- Pods/Local Podspecs/ReactNativeDependencies.podspec.json

Reviewed By: christophpurrer

Differential Revision: D104889112

Pulled By: CalixTang

fbshipit-source-id: 97505a8bf78f7df57bda2d87705da5a20c934d2b
Summary:
Pull Request resolved: #56812

Update load-bearing `react/react-native-devtools-frontend` URLs following repo move. In particular, the `sync-and-build` script.

URLs in code comments are preserved (rely on redirect / avoid churn).

Changelog: [Internal]

___

overriding_review_checks_triggers_an_audit_and_retroactive_review
Oncall Short Name: react_native_iroc

Differential Revision: D105033074

fbshipit-source-id: 78545cb92d9623d9a115d1a940ba7efc78a5a6d8
#56814)

Summary:
Pull Request resolved: #56814

Any time we have a non-nullable accessibilityState prop, it appears to always set `expanded` false, which causes most Android screen readers to append or prepend "collapsed". This fixes the issue.

## Changelog
[Android][Fixed] Screen reader behavior for accessibilityState expanded

Reviewed By: javache

Differential Revision: D105035390

fbshipit-source-id: 4b3b1b2a9b6e661cfde0f39d7de6a7cd7af91bb0
…dTouchTrack (#56819)

Summary:
Pull Request resolved: #56819

The native iOS touch system can occasionally dispatch touch events to JavaScript where `nativeEvent.changedTouches` is undefined due to inconsistencies between local and UIKit touch registries. This causes a TypeError crash in `ResponderTouchHistoryStore.recordTouchTrack` when it unconditionally calls `.forEach()` on `changedTouches`.

The fix adds a defensive null check: if `changedTouches` is null/undefined, we log a DEV warning and bail out early from `recordTouchTrack`. Additionally, `nativeEvent.touches` accesses use optional chaining to prevent secondary crashes.

Changelog: [iOS][Fixed] - Fix TypeError crash in ResponderTouchHistoryStore when changedTouches is undefined

Reviewed By: fkgozali

Differential Revision: D105023000

fbshipit-source-id: d3ade24e93f45614b094932e436f7190c8c0a985
Summary:
Pull Request resolved: #56746

Add an RNTester PlatformTest case that calls Image.getSize against a small PNG, a large JPEG, and an EXIF-rotated JPEG, then verifies the dimensions reported by native image metadata. Extend the existing Image Maestro flow to open the new test and wait for the pass result, so the same flow can run against Android and iOS RNTester builds.

Changelog:
[Internal][Added] - Add RNTester device coverage for Image.getSize dimensions

Reviewed By: christophpurrer

Differential Revision: D104535939

fbshipit-source-id: 4f181ce7320af679dd4c409a5c813555914e580c
Summary:
Pull Request resolved: #56808

Adds a `--watch` flag to `yarn build-types`. Helpful when debugging output TS types end-to-end.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D104815967

fbshipit-source-id: 23ca53bffd5b0508272a5fad8bd4ca4314bb9d06
Summary:
Pull Request resolved: #56824

Update the `simplifyTypes` transform (Flow → TS generation) to prune non-overlapping keys from `Omit<>` helpers in TypeScript `interface` unions.

This greatly reduces API snapshot churn/inflation in the next two diffs, which convert a number of `type` declarations (trivial unions) to `interface` (`Omit<>` required for correct union).

#### In detail

`flow-api-translator` emits `Omit<ParentType, keys>` to faithfully translate Flow's object spread override semantics to TypeScript.

```
// Flow
type Base = {x: string, y: number};
type Child = {...Base, x: boolean}; // Later properties in an object spread override earlier ones

// TypeScript
type Base = {x: string; y: number};
type Child = Omit<Base, "x" | "y"> & {x: boolean};  // Later properties in an object spread *merge*, rather than override. So we must use Omit<> for matched keys.
```

For `interface` type unions with overlapping keys, this can result in a number of unnecessary lines in the API snapshot, with little/no human readable value.

This diff extends existing `Omit<>` handling by `simplifyTypes` to recursively resolve all property keys reachable from a type, and prune keys that don't exist on the parent type.

```
// TypeScript
type Child = Omit<Base, "x"> & {x: boolean};  // Only "x" matched - strip `| "y"`
type ChildTwo = Base & {z: string};  // No property collision - strip entire `Omit<>`
```

- See changes to `ReactNativeApi.d.ts`, [P2325468482](https://www.internalfb.com/phabricator/paste/view/P2325468482?view=diff) for examples.
- **Decision point**: This diff opts to preserve correctness in TS — even though the snapshot isn't/isn't intended to be read directly/programatically, vs the conciseness tradeoff if we dropped all `Omit<>`s (human readable but ambiguous to the typechecker).

Changelog: [Internal] - JS API snapshot changes are a simplification refactor only

Reviewed By: robhogan

Differential Revision: D105150070

fbshipit-source-id: 43b0ef517164332a5cfaee7a5de5747749ac5e7c
Summary:
Pull Request resolved: #56822

Changelog: [Internal]

Reviewed By: thegreatercurve

Differential Revision: D104870951

fbshipit-source-id: 3b4bc9664ec1088eb944e68bf958e5e2b7b2d74c
…sabling block-scoping transform for SH (#56825)

Summary:
Pull Request resolved: #56825

Disable `babel/plugin-transform-block-scoping` when `customTransformOptions.unstable_preserveBlockScoping` is truthy. This allows us to experiment with native let/const block scoping support in Static Hermes.

Changelog: [Internal]

Reviewed By: vzaidman

Differential Revision: D93013927

fbshipit-source-id: 6e2c1274426943fcf1ce5a8c09d677e1d0afb35f
…56801)

Summary:
Pull Request resolved: #56801

In preparation for enabling `enableSyncVoidMethods` (D104331837), which makes TurboModule void methods execute synchronously on the JS thread instead of being dispatched asynchronously.

Currently, this module overrides `methodQueue` to return `dispatch_get_main_queue()` so its void methods execute on the main thread. When `enableSyncVoidMethods` is enabled, the `methodQueue` override is ignored for void methods — they execute directly on the JS thread. This causes crashes for any UI operations that must run on the main thread.

**Fix:** Remove the `methodQueue` override. The `alertWithArgs` method already dispatches UI work onto the main thread via `RCTExecuteOnMainQueue`, so it is already safe.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D104771644

fbshipit-source-id: 4f1eae55c64e56990efc20c4b32af1d722520037
Summary:
Pull Request resolved: #56806

Pull Request: #56806

Bump hermes-parser and related packages to 0.36.1.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D104122338

fbshipit-source-id: 7e938ec114355cf517ff2e76ffbb941f6352d213
Summary:
## Why
Kotlin 2.2 changes the ABI for interface methods with default implementations. In Kotlin 2.1, these were emitted as 'public abstract' in the bytecode. In Kotlin 2.2, they are emitted as 'public' (non-abstract) with DefaultImpls. This causes React Native's binary compatibility validator to detect API changes.

No impact on actual functionality:

https://kotlinlang.org/docs/whatsnew22.html#changes-to-default-method-generation-for-interface-functions

The new methods that appear in bytecode are expected, since they weren't overridden in the class.

Updated ReactAndroid.api dump file by running:
buck2 run //xplat/js/scripts/rn-api:generate-rn-api-metadata

Affected interfaces:
- ReactMarker.FabricMarkerListener
- AppearanceModule.OverrideColorScheme
- RCTEventEmitter
- RCTModernEventEmitter
- ReactNativeHost (new methods: getBundleFilePath, setBundleFilePath)
- DialogRootViewGroup (new method: onChildStartedNativeGesture)

## Changelog
[Internal] [Changed] -
Pull Request resolved: #56833

Reviewed By: cortinico

Differential Revision: D105216824

fbshipit-source-id: df5dede0b3d72b9fd1d6d89f377fa07f744a1c61
Summary:
Pins the default `GITHUB_TOKEN` to `contents: read` on 2 workflows in `.github/workflows/` that don't call a GitHub API beyond the initial checkout.

The following files were left implicit because they reference `GITHUB_TOKEN` / use a write-scope action / trigger on `pull_request_target`. Those scopes are best declared by maintainers: `cache-reaper.yml`, `check-for-reproducer.yml`, `retry-workflow.yml`, `validate-dotslash-artifacts.yml`.

## Why

CVE-2025-30066 (March 2025 `tj-actions/changed-files` supply-chain compromise) exfiltrated `GITHUB_TOKEN` from workflow logs. Pinning per workflow caps runtime authority irrespective of the repo or org default, gives drift protection if the default ever widens, and is credited per-file by the OpenSSF Scorecard `Token-Permissions` check.

YAML validated locally with `yaml.safe_load` on each touched file.

## Changelog

[Internal] [Changed] -

Pull Request resolved: #56834

Reviewed By: cipolleschi

Differential Revision: D105294446

Pulled By: cortinico

fbshipit-source-id: c90e885345f7b49d6c3ccfd73fdbd7ce8eebe4a1
Summary:
Pull Request resolved: #56826

This class was fully stubbed out as part of the Legacy Architecture removal. All public methods had empty bodies or returned null/0, meaning any OSS library still referencing it was already silently broken at runtime.

- `UIImplementation` — all methods empty stubs

Also removes the dead `getUIImplementation()` method from `UIManagerModule`, and cleans up stale Javadoc references in `JSTouchDispatcher`, `ReactViewGroup`, and `ReactInterceptingViewGroup`.

`UIBlock`, `NativeViewHierarchyManager`, `UIViewOperationQueue`, and the `addUIBlock`/`prependUIBlock` methods on `UIManagerModule` are retained and will be deprecated in a follow-up diff.

Changelog:
[Android][Removed] - Remove legacy architecture stub `UIImplementation`. This class was already non-functional (all methods were empty stubs).

Reviewed By: christophpurrer

Differential Revision: D104991922

fbshipit-source-id: 8a4bb015453f2bf441deec9ac914b08642faab44
Summary:
X-link: facebook/yoga#1939

Pull Request resolved: #56780

Migrate YogaNodeJNIBase.java to YogaNodeJNIBase.kt, the last hand-written Java source file in the Yoga core library. This required converting all function overrides to Kotlin property overrides where the abstract YogaNode class declares them as val/var properties. Also changed nativePointer visibility in YogaConfigJNIBase from protected to internal to maintain same-module access that Java protected provided via package access.

Changelog:
[Internal] -

Reviewed By: alanleedev

Differential Revision: D104666335

fbshipit-source-id: c60285453e8a6ec834924be461da3c669d9a7be4
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 15, 2026
@cipolleschi cipolleschi changed the title Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative [0.81][iOS] Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative May 15, 2026
Currently, Hermes, ReactNativeDependencies, and ReactNativeCore
tarballs are cached only inside the Pods/ directory. This means
every clean `pod install` (or deleting the Pods folder) triggers
a full re-download from Maven, even if the same version was already
downloaded before.

This adds a shared cache layer at ~/Library/Caches/ReactNative/.
On first download, tarballs are saved to the shared cache. On
subsequent pod installs, if the local Pods cache is empty but the
shared cache has the tarball, it is copied locally instead of
re-downloaded. This benefits:
- Clean installs after deleting Pods/
- Multiple projects using the same React Native version
- CI environments with a persistent home directory

Added descriptive log messages for each scenario (local hit,
shared cache hit, cache miss + download) to aid debugging.
@cipolleschi cipolleschi force-pushed the cipolleschi/shared-cache-prebuilt-binaries branch from cd6aaa7 to 2092992 Compare May 15, 2026 13:30
Comment thread .github/workflows/prebuild-ios-core.yml Outdated
Comment on lines +138 to +142
needs: [generate_changelog, set_hermes_version]
uses: ./.github/workflows/create-draft-release.yml
secrets: inherit
with:
hermesVersion: ${{ needs.set_hermes_version.outputs.HERMES_VERSION }}
Comment on lines +29 to +51
runs-on: ubuntu-latest
if: github.repository == 'facebook/react-native'
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Setup node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
uses: ./.github/actions/yarn-install
- name: Configure Git
shell: bash
run: |
git config --local user.email "bot@reactnative.dev"
git config --local user.name "React Native Bot"
- name: Validate DotSlash artifacts
uses: actions/github-script@v8
with:
script: |
const {validateDotSlashArtifacts} = require('./scripts/releases/validate-dotslash-artifacts.js');
await validateDotSlashArtifacts();
Fetches the .sha1 checksum from Maven for each downloaded tarball
and validates file integrity at two points:

1. When reading from the shared cache: if the cached file's SHA1
   doesn't match Maven's, it is treated as corrupted and
   re-downloaded, replacing the stale cache entry.
2. After a fresh download: validates the download succeeded
   correctly before saving to the shared cache. If verification
   fails, the file is not cached (but still used locally, as
   CocoaPods will re-extract it).

If Maven doesn't serve a .sha1 for a given artifact (e.g. some
nightly builds), validation is skipped gracefully.
Moves shared_cache_dir, fetch_maven_sha1, and validate_tarball
into ReactNativePodsUtils in utils.rb to eliminate duplication
across hermes-utils.rb, rndependencies.rb, and rncore.rb.
hermes-utils.rb cannot use require_relative to utils.rb because
the folder structure differs between the monorepo and published
npm package. Instead, hermes-utils.rb gets its own copy of
shared_cache_dir, fetch_maven_sha1, and validate_hermes_tarball.

Also adds explicit "Verifying checksum for cached/downloaded ..."
log lines in all three download functions so the verification
step is visible in pod install output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Facebook Partner: Facebook Partner Pick Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.