Skip to content

chore(0.86): prepare stable 0.86.0 with React Native 0.86.3 - #3036

Open
Saad Najmi (Saadnajmi) wants to merge 78 commits into
microsoft:0.86-mergefrom
Saadnajmi:0.86/release
Open

Saad Najmi (Saadnajmi) wants to merge 78 commits into
microsoft:0.86-mergefrom
Saadnajmi:0.86/release

Conversation

@Saadnajmi

@Saadnajmi Saad Najmi (Saadnajmi) commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Current release stack

Depends on #3035. RNM 0.86.0 with RN 0.86.3; retain a separate stable release branch.

Validation and backups

The branch-specific repaired source passed hardened immutable installation, constraints, and its complete release-helper selection. The selected 18-head packet records 1,406 passing helper tests. Exact source-tree equivalence is used for rewritten endpoints where applicable; the two changed linear RC checkpoints were tested separately.

Native/API evidence retains its recorded scope. The SwiftPM and RNTester repairs have six focused native build passes. Public stable versions and runtime/API contents were preserved except for the independently reviewed SwiftPM destination repair where applicable.

Public-registry lock correction passed all 18 hosted generation, hardened immutable, constraints, and metadata-audit jobs in run 35769816507. Only equivalent executable-path spelling changes are permitted; dependency versions, checksums, and ranges are unchanged. The previous functional test results remain applicable to this metadata-only correction. Fresh GitHub CI and review remain required. Previous heads are preserved on the same repository under backup/pre-ci-repair-20260922/<original-branch> and backup/pre-public-registry-20260922/<original-branch>; local complete-history bundles were verified as well.

The 0.87 PR sequence is one first-parent path: #3037#3104#3105#3106#3100#3101#3107. The redundant #3102/#3103 reviews are consolidated into #3105.

This section supersedes earlier stack order, source identity, and validation-status notes below.


Summary

Merges the pinned React Native 0.86-stable tip a8eb4f70c730bc3ee3dba4d9b1ca6f70f0d674d3 (react-native@0.86.0) into the judged React Native macOS 0.86-merge tip db92dc832747c4ad003d8fe12da35f7dc56880b4.

Final head: fc0be7349d1aeda36f26b26d57d97f6674fd2e08.

This PR remains draft while the release stack and breaking API report receive human review.

After the 0.86-merge work lands and the future Microsoft 0.86-stable branch exists, retarget this PR from 0.86-merge to 0.86-stable.

Release metadata

  • Seeds react-native-macos and @react-native-macos/virtualized-lists at 0.86.0-rc0.
  • Pins the public React Native peer/dependency surface to exact 0.86.0.
  • Adds a patch Changeset that materializes both public packages as 0.86.0; changelog/version materialization remains deferred to the Changesets action PR.
  • Aligns private/upstream workspace package versions with repository constraints.
  • Uses production Hermes V1 250829098.0.14.

Merge conflicts

The ordered merge had 22 conflicted paths and 85 textual conflict blocks, with no deleted/absent tree terms. A textual conflict block is one serialized <<<<<<< conflict N of M block; the per-file hunk counts below sum to the same 85 blocks.

Each block represents three conceptual merge-expression tree terms: one parent snapshot, one base diff from term, and the other parent to term. Across the merge, that is 255 conceptual terms (85 + 85 + 85), not 255 hunks. The raw serialization has two term-header markers per block (+++++++ and %%%%%%%), for 170 term-header markers and 340 total marker/header lines including 85 opening and 85 closing markers; ordinary body +/- lines are excluded.

  • package.json
  • packages/babel-plugin-codegen/package.json
  • packages/community-cli-plugin/package.json
  • packages/dev-middleware/package.json
  • packages/eslint-config-react-native/package.json
  • packages/eslint-plugin-specs/package.json
  • packages/jest-preset/package.json
  • packages/metro-config/package.json
  • packages/react-native/ReactNativeApi.d.ts
  • packages/react-native/package.json
  • packages/react-native/sdks/.hermesv1version
  • packages/react-native/sdks/.hermesversion
  • packages/react-native-babel-preset/package.json
  • packages/react-native-babel-transformer/package.json
  • packages/react-native-compatibility-check/package.json
  • packages/react-native-popup-menu-android/package.json
  • packages/rn-tester/Podfile.lock
  • packages/rn-tester/package.json
  • packages/virtualized-lists/package.json
  • private/helloworld/package.json
  • private/react-native-codegen-typescript-test/package.json
  • yarn.lock

Textual conflict blocks are categorized exactly as follows:

  • Metadata/version/structural: 25
  • Generated JavaScript API: 25
  • Generated CocoaPods lock: 34
  • Generated Yarn lock: 1
  • Total: 85

Within the metadata/version/structural blocks, resolutions preserve macOS package identities and public/private boundaries while adopting stable package versions, exact dependency references, and Hermes pins. Generated outputs were regenerated in dedicated layers. The 22 textual merge-conflict paths introduced no additional conflict class beyond the categories above.

Novel semantic conflict

The post-merge Changesets gate found one separate novel release-tooling/default-value conflict in .github/scripts/change.mts; it is not part of the 22 paths or 85 textual conflict blocks above.

  • Provenance: 697e23ee9b209061509158fef72ce63b29c91a54 introduced (repoPath && match) ?? 'origin' during the Changesets migration.
  • Failure: when root repository metadata is empty, the left side evaluates to ''; ?? preserves that empty string and produces /0.86-merge.
  • Fix: 6effc07b5625b35940d09545f209e1d3addf9740 changes the default to || 'origin' in .github/scripts/change.mts.
  • Tag compliance: the changed line carries an inline // [macOS] tag, and the .mts-inclusive diff-tag scan has zero new suspect keys.
  • Focused mainline candidate: extract commit 6effc07b as a one-path PR because it fixes yarn change/change:check remote detection generally when repository metadata is missing or empty. Do not duplicate it on this release branch.

Reviewer decisions

  • Preserve the judged single-source Fabric host/coordinator ownership in SwiftPM and CocoaPods.
  • Preserve the frame-timing observer guard, AppKit loading-window behavior, RedBox/RCTUIKit surfaces, key APIs, absolute-path Codegen fix, and workspace parser tooling.
  • Adopt stable Apple changes for portable PODFILE_DIR, umbrella/module-map macro visibility, prebuilt artifact caching, and Unicode-safe pod URIs.
  • Adopt the shared Pressable PlatformColor/alpha behavior while retaining macOS API generation.
  • Keep Hermes V1 production preparation and macOS XCFramework recomposition at 250829098.0.14.
  • Review the regenerated JavaScript API report: comparison with the pre-sync parent is classified BREAKING with 51 changed APIs.

Commit layers

  • 2a4c2e178f0af714ae1dd6856b6c4797bee005b2 — ordered merge and conflict resolutions
  • 6ecb2fcfa526003e8ebf2b917d91bd426681f1b8 — dependency metadata
  • e394cab81613bf1c4b8fdc0466af3b399d922257 — JavaScript API snapshot
  • 8e1e7a065b0ec246894e72608824ae42bb27c3e9 — C++ API snapshots
  • e1f0a7ca6ff9cc7b5d64460e481662c7ef9752a2 — Jest snapshots
  • 23917136417b445b3cfc9411596cfb39badb905e — CocoaPods metadata
  • e72e7b6928aba103adc248c12140db1d41076318 — release package constraints
  • 6effc07b5625b35940d09545f209e1d3addf9740 — Changesets base detection
  • fc0be7349d1aeda36f26b26d57d97f6674fd2e08 — final CocoaPods lock refresh

Validation

  • Topology, ancestry, connectivity, parent ordering, trailers, conflict markers, and clean-tree checks
  • yarn install --immutable
  • yarn constraints
  • GITHUB_BASE_REF=0.86-merge yarn change:check
  • yarn changeset status --since=origin/0.86-merge
  • yarn lint
  • yarn format-check
  • yarn test-typescript
  • yarn build-types
  • yarn test-generated-typescript
  • yarn flow-check
  • yarn test --runInBand --forceExit
  • yarn build
  • yarn cxx-api-validate
  • swift package dump-package for React and ReactNativeDependencies
  • CocoaPods deterministic install with pinned Hermes V1
  • Production Hermes V1 Release download and macOS XCFramework recomposition
  • Release prebuilds for iOS device, iOS simulator, macOS, visionOS device, and visionOS simulator
  • Final five-slice React XCFramework composition
  • RNTester Debug builds for macOS, iOS simulator, and visionOS simulator
  • Full external diff-tag scan, including multiline conditions and .mts files
  • Recursive dependency audit with target-level comparison to the judged parent

All 278 Jest suites passed: 5,650 tests passed, 2 skipped, and 1,803 snapshots passed. All six C++ API snapshots validated. Both public Changeset releases resolve to 0.86.0.

Validation caveats

  • The first Jest run passed all tests but retained asynchronous handles; the same immutable export passed with --forceExit.
  • Initial Xcode attempts stalled while another release workspace held the global Xcode writer slot. After that stale writer exited, all five prebuild slices, XCFramework composition, and all three RNTester platform builds passed sequentially on the same exact head.
  • The macOS Release prebuild used the recomposed Hermes V1 XCFramework with its macOS slice. RNTester Debug builds used the matching Debug Hermes V1 artifact and refreshed only the local pod sandbox; the committed lock remains deterministic.
  • The dependency audit remains red for 33 inherited high/critical advisory IDs. The exact judged-parent comparison contains the same 33 IDs, with zero new or worsened advisory keys.

Diff-tag contract

The canonical guide is byte-identical to the judged parent. The final full fork-delta scan found zero new suspect keys; all retained findings, generated outputs, structural platform files, file-level tags, and multiline conditions are classified in the external release artifacts. The independent release judge should repeat this audit from the final head.

Final CI follow-up

Source validation is reused through exact tree equality:

  • No source-tree changes. The commit aligns this already-passing stable branch with its corrected mainline predecessor.

The complete 16-head batch passed 92 recorded validation commands, including branch-specific API revalidation/generated TypeScript, full formatting checks, and combined targeted suites where applicable. Native changes are limited to the reviewed #3033 destination guards (also present in stable 0.85) and #3104's sidecar-copy correction (already present in its descendants). Exact source equivalence preserves earlier native results elsewhere. The public-registry lockfiles and package manifests remain byte-identical.

Previous heads are backed up at backup/pre-ci-followup-20260922/<original-branch> on their source repository. Fresh current-head CI remains required. The one-first-parent 0.87 sequence is preserved.

Rob Hogan (robhogan) and others added 30 commits May 5, 2026 18:10
#publish-packages-to-npm&next
Summary:
`PODFILE_DIR` was being set to `Pod::Config.instance.installation_root.to_s`, which bakes the contributor's absolute path (e.g. `/Users/alice/Projects/MyApp/ios`) into `project.pbxproj` — every `pod install` on a different machine churns the diff, and a checked-in pbxproj points at someone else's filesystem.

Set `PODFILE_DIR` per-project via Xcode variable substitution: `$(SRCROOT)` for user projects, `$(SRCROOT)/..` for the Pods project. Resolved value is identical at build time; the persisted string is now machine-independent.

## Changelog:

[IOS] [FIXED] - Persist `PODFILE_DIR` as `$(SRCROOT)`-relative so `project.pbxproj` is portable across machines

Pull Request resolved: react#56732

Test Plan:
1. `pod install`, inspect host-app and Pods `pbxproj`: `PODFILE_DIR` should be `$(SRCROOT)` and `$(SRCROOT)/..`, not an absolute path.
2. Build the app and confirm consumers of `${PODFILE_DIR}` still resolve correctly (`with-environment.sh`, codegen script phases).

Reviewed By: christophpurrer

Differential Revision: D104398698

Pulled By: cipolleschi

fbshipit-source-id: e00f027d5c3570ac1a9c78b54fdbdaf81f98f17f
…56736)

Summary:
`Image.getSize` and `getSizeWithHeaders` call Fresco's `fetchDecodedImage`, which returns a `CloseableImage` whose width / height reflect the bitmap after Fresco's automatic downsampling (typically capped at the screen size).

For sources larger than the screen this returned the wrong dimensions. ex: a 4000x3000 image on a 1920x1080 device came back as 1920x1440.

Switch to `fetchEncodedImage` and read the dimensions from the parsed image metadata (JPEG / PNG / WebP / HEIF headers), so the values are the true source dimensions. Swap width / height for 90°/270° EXIF rotation to match the iOS behavior in `RCTImageLoader`.

Fixes react#33498
Closes facebook/fresco#2236

## Changelog:

<!-- 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

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [FIXED] - `Image.getSize` and `Image.getSizeWithHeaders` now return the true source dimensions instead of Fresco's downsampled values

Pull Request resolved: react#56736

Test Plan:
In the RNTester app, add:

```ts
useEffect(() => {
  Image.getSize(
    'https://images.pexels.com/photos/842711/pexels-photo-842711.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
    (width, height) => {
      console.log({width, height});
    },
  );
}, []);
```

### Before

<img width="811" height="467" alt="before" src="https://github.com/user-attachments/assets/6fb401ed-cf5a-4496-bcc1-4cfd243bc0b7" />

### After

<img width="811" height="467" alt="after" src="https://github.com/user-attachments/assets/dc809d5f-c554-45d6-a3a3-7712bf39ac44" />

Reviewed By: javache

Differential Revision: D104533593

Pulled By: Abbondanzo

fbshipit-source-id: f087d528474c40cffbf24eb1e3958b4b18fb118e
#publish-packages-to-npm&next
…wildcard so RCT_* macros stay visible (react#56862)

Summary:
When `RCT_USE_PREBUILT_RNCORE=1` (the 0.84+ default) and a consumer pod builds under `use_frameworks!`, RCT macros like `RCT_EXTERN`, `RCT_EXTERN_C_BEGIN`, `RCT_EXPORT_METHOD`, `RCT_REMAP_METHOD` fail to propagate.

The `.m` files using these macros hit cascading parse errors like :
- `unknown type name 'RCT_EXTERN_C_BEGIN'` in `<React/RCTBridgeModule.h>` line 51,
- `unknown type name 'RCT_EXTERN'` in `<React/RCTEventDispatcherProtocol.h>` line 17,
- and `type specifier missing, defaults to 'int'` on every `RCT_EXPORT_METHOD(...)` call site.

Root cause is in two places in `packages/react-native/scripts/ios-prebuild/templates/`:

1. `React-umbrella.h` orders `RCTBridgeConstants.h` (line 56) before `RCTDefines.h` (line 84). `RCTBridgeConstants.h` uses `RCT_EXTERN` at its first declaration but the macro is only defined later in `RCTDefines.h`. When the umbrella is loaded as a single parse context, the `RCT_EXTERN` use is unresolvable.

2. `module.modulemap` declares `module * { export * }` inside both `framework module` blocks, which creates an inferred submodule per header. That isolates macro `#define`s into per-header parse scopes. Even fixing the umbrella order, sibling submodules don't share macros: macros defined in the `RCTDefines.h` submodule are invisible to the `RCTBridgeConstants.h` submodule, and to consumers of the `React` module.

This PR fixes both:

- Move `#import <React/RCTDefines.h>` to the very top of the umbrella (right after the prologue and before any other `<React/...>` import), with a comment explaining why ordering matters.
- Remove the `module * { export * }` wildcard from both `framework module` blocks in the modulemap. The umbrella header alone is sufficient to declare the module's contents, and dropping the wildcard means the whole module shares one parse context where macros propagate.

The combination of `use_frameworks!` + prebuilt RNCore is the path of least resistance today: `use_frameworks!` is the Expo default and is required by `firebase-ios-sdk` for its Swift bridges. Prebuilt RNCore is the 0.84+ default. The colliding defaults break native-module ecosystems like `react-native-firebase` that consume the RCT macros. Producer-side fix is in flight at invertase/react-native-firebase#9024; this PR closes the consumer side.

## Changelog:

[IOS] [FIXED] - Load `RCTDefines.h` first in the prebuilt React umbrella and drop the `module *` submodule wildcard so RCT_* macros propagate to consumer pods under `use_frameworks!`.

Pull Request resolved: react#56862

Test Plan:
Reproduced on RN 0.85.3 (latest stable at time of writing) on macOS 26.3.1 / Xcode 26.5 / iOS 26.5 Simulator (iPhone 17 Pro).

**Reproducer setup**

Fork of `mikehardy/rnfbdemo` with these adjustments in `make-demo.sh`:
- `RN_VER=0.85.3`
- `RNFB_VER=24.0.0`
- `FB_IOS_VER=12.10.0`
- Remove `react-native-firebase/dynamic-links` from the bulk yarn add (deprecated and removed in RNFB 24.x).

Default Podfile mods produced by `make-demo.sh` are preserved: `use_frameworks! :linkage => :static` + `$RNFirebaseAsStaticFramework = true`. No `RCT_USE_PREBUILT_RNCORE` override (stays at the `1` default).

Public reproducer: https://github.com/wneel/rnfbdemo (see its `REPRO.md` for the two-stage flow).

The reproducer also has invertase/react-native-firebase#9024 (producer-side podspec fixes) applied as an overlay. Without those, the build fails earlier at `-Wnon-modular-include-in-framework-module`. With them applied, the build progresses to the consumer side and surfaces the macro propagation bug this PR fixes.

**Before this PR**

Same reproducer config. iOS build fails on consumer pods (RNFBAuth, RNFBStorage, RNFBMessaging) with:

```
.../Pods/Headers/Public/React-Core/React/RCTEventDispatcherProtocol.h:17:1: error: unknown type name 'RCT_EXTERN'
.../Pods/Headers/Public/React-Core/React/RCTEventDispatcherProtocol.h:17:27: error: expected ';' after top level declarator
.../node_modules/react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h:26:21: error: declaration of 'RCTPromiseRejectBlock' must be imported from module 'RNFBApp.RNFBAppModule' before it is required
```

**After this PR**

Same reproducer config builds cleanly: `pod install` clean, `xcodebuild` Debug build produces the app, zero `RCT_EXTERN` macro errors anywhere in the log.

Verified by editing `packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h` and `packages/react-native/scripts/ios-prebuild/templates/module.modulemap` in place (the diff in this PR), regenerating the prebuilt React.xcframework artifact, and re-running the reproducer.

**Output of `npx react-native-community/cli info` from the reproducer environment:**

```
System:
  OS: macOS 26.3.1
  CPU: (10) arm64 Apple M2 Pro
  Memory: 466.16 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.14.0
    path: /usr/local/bin/node
  Yarn:
    version: 3.6.4
    path: /usr/local/bin/yarn
  npm:
    version: 11.12.1
    path: /usr/local/bin/npm
  Watchman:
    version: 2026.05.11.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.5
      - iOS 26.5
      - macOS 26.5
      - tvOS 26.5
      - visionOS 26.5
      - watchOS 26.5
IDEs:
  Xcode:
    version: 26.5/17F42
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 21.0.9
    path: /usr/bin/javac
```

**Cross-references**

- `react-native-firebase` producer-side fix in flight: invertase/react-native-firebase#9024
- `react-native-firebase` `.m` import hygiene follow-up: invertase/react-native-firebase#9026
- Original RNFB user-facing issue: invertase/react-native-firebase#8883

Reviewed By: cortinico

Differential Revision: D105582598

Pulled By: cipolleschi

fbshipit-source-id: ab364d46fc94d64274197cdd717a06e425a9324f
…ks (react#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: react#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:
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

Pull Request resolved: react#56847

Test Plan:

```
[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
```

```
[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.
```

```
[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
```

Reviewed By: cortinico

Differential Revision: D105315202

Pulled By: cipolleschi

fbshipit-source-id: 3196d589f59b8edc75e62752d0c61c3618c1be90
Summary:
`android_ripple` on `Pressable` (and `TouchableNativeFeedback.Ripple()`) only
accepted numeric (pre-processed ARGB int) colors. Passing a `PlatformColor`
would throw an invariant in JS, making theme-aware ripple colors impossible.

This PR removes those guards and wires up the full color pipeline:

1. **JS** (`useAndroidRippleForView.js`, `TouchableNativeFeedback.js`):
   removed the `invariant` that rejected non-numeric processed colors.
   `TouchableNativeFeedback.Ripple()` now accepts `ColorValue` instead of
   `string`.
2. **C++** (`NativeDrawable.h`, `HostPlatformViewProps.cpp`): `color`
   changed from `int32_t` to `SharedColor` + a separate `colorResourcePaths`
   field for `PlatformColor` resource paths. The `fromRawValue` pipeline now
   resolves both plain colors and `PlatformColor` objects.
3. **Kotlin** (`ReactDrawableHelper.kt`): `getColor()` now handles both
   numeric and `PlatformColor` map values via `ColorPropConverter.getColor()`,
   catching `JSApplicationCausedNativeException` to fall back gracefully
   instead of crashing.
4. **Theme change support** (`ReactViewGroup.kt`): the raw drawable
   description maps are retained on the view, and `onConfigurationChanged`
   re-applies them so ripple colors update automatically on light/dark mode
   switch.

A new `alpha: number` (0–1) field is also added so users can apply opacity to
a `PlatformColor` whose value is fully opaque and can't have alpha embedded at
the JS level. It is applied by multiplying into the resolved color's alpha
channel.

Unresolvable `PlatformColor` resources are handled gracefully: on New Arch,
C++ omits the `color` key so Kotlin falls back to `colorControlHighlight`; on
Old Arch, `ReactDrawableHelper` catches the `JSApplicationCausedNativeException`
and falls back to `colorControlHighlight` instead of crashing.

[ANDROID] [ADDED] - `android_ripple` now accepts `PlatformColor` for
theme-aware ripple colors, and a new `alpha` (0–1) parameter for controlling
ripple opacity independently of the color value.

Pull Request resolved: react#56395

Test Plan:
**Automated:**
- Existing Pressable snapshot tests pass unchanged.
- Updated snapshot for `PlatformColor + alpha` to use `?attr/colorAccent`
  (matching the RNTester example).
- Added snapshot test `should not crash with an unresolvable PlatformColor`
  verifying the component renders at the JS level without throwing.

**Manual (RNTester → Pressable → "Pressable with PlatformColor ripple and alpha"):**
1. `PlatformColor('?attr/colorAccent'), no alpha` → full-opacity accent ripple
2. `PlatformColor('?attr/colorAccent'), alpha=0.3` → 30% opacity accent ripple
3. `#FF0000, no alpha` → full red ripple (regression check)
4. `#FF0000, alpha=0.5` → 50% opacity red ripple
5. Toggle system light/dark mode → ripple color updates automatically
6. Pass an intentionally invalid attribute (e.g. `?attr/doesNotExist`) → no
   crash, ripple falls back to default `colorControlHighlight` grey

[Screen_recording_20260410_091000.webm](https://github.com/user-attachments/assets/5607d267-8cf1-4bbe-bad1-a80aac82d027)

> [!NOTE]
This is required in [React Native Paper](https://github.com/callstack/react-native-paper) to be able to fully support the Material Design specs but also useful as a general purpose feature for providing more flexibility when customizing ripple color.

Reviewed By: javache

Differential Revision: D105819708

Pulled By: fabriziocucci

fbshipit-source-id: d27c43e0b4e619b6af1c8de0cdb2882db05ee33c
Summary:
react#56878 shows that using unicode characters in paths fails with pod install.

Expo fixed this internally here: expo/expo#45779

Fixes react#56878

## How:

Build local `file://` sources through a shared helper that percent-encodes filesystem paths before passing them to `URI::File.build`. This avoids Ruby/CocoaPods URI failures when React Native projects or local prebuilt tarballs live under paths containing Unicode characters or spaces.

Apply the helper to `RNCore` and `ReactNativeDependencies` local tarball sources, including RNCore dSYM-processed prebuilt paths, while leaving remote Maven and Sonatype URLs unchanged.

Add focused coverage for Unicode, spaces, ASCII paths, and the raw `URI::File.build` regression case.

## Changelog:

[IOS] [FIXED] - fixed escaping local file URIs for unicode paths in ruby scripts

Pull Request resolved: react#56907

Test Plan: - Test with creating a new project in a path containing a unicode character and the run pod install.

Reviewed By: cortinico

Differential Revision: D105968728

Pulled By: cipolleschi

fbshipit-source-id: 6d5b9043aafe3d86494f3b5ca0f208e46f1f3739
#publish-packages-to-npm&next
#publish-packages-to-npm&next
#publish-packages-to-npm&latest
…t-native (react#57167)

Backport of react#57167 to 0.86-stable.

Update GitHub Actions workflow fork-prevention guards
(github.repository == ...) and the monitor-new-issues repo_owner
parameter to reflect React Native's migration from
facebook/react-native to react/react-native.

This is the equivalent of upstream commit
861d8e0; applied manually because the
workflow files have diverged on this branch and a direct cherry-pick
conflicts.
Backport of react#57216 to 0.86-stable.

Move CI jobs off the timing-out 4-core-ubuntu / 8-core-ubuntu runners
to ubuntu-latest across the Android, fantom, build and publish
workflows. macOS runners are unchanged.

This is the equivalent of upstream commit
097dbc2; applied manually because the
workflow files have diverged on this branch and a direct cherry-pick
conflicts.
On pull_request events github.ref_name is "<pr-number>/merge", which never
matches *-stable*, so the template E2E always cloned the template's main
branch. Template main now ships a Gradle 9.4.1 wrapper (bundling Kotlin
2.3.0), whose metadata the Kotlin 2.1.0 compiler used by
@react-native/gradle-plugin on 0.86 cannot read, breaking
:gradle-plugin:settings-plugin:compileKotlin on every PR to 0.86-stable.

Use github.base_ref (set on PR events) so PRs targeting stable branches
check out the matching template branch, falling back to ref_name for
branch pushes.
Aligns 0.86 with the Hermes version shipped in 0.87 RCs, which includes
a fix for excessive memory consumption in older Hermes versions.
…eact#57103) (react#57244)

Summary:
Pull Request resolved: react#57103

Changelog: [General][Fixed] Fixed `display: contents` nodes having `hasNewLayout` set incorrectly

`cleanupContentsNodesRecursively` unconditionally sets `hasNewLayout=true` on `display: contents` children, including on code paths where their parent's layout was not actually performed in this pass. The stale flag can survive across layout passes and, in clone-on-write renderers (e.g. React Native Fabric), be observed by a subsequent pass whose parent was cloned but whose layout was served from cache, leaving the contents child's owner pointing at the previous parent revision.

There are two paths through which the cleanup could stamp a contents child whose parent's `hasNewLayout` would end up false:

1. Measure-phase visit. Inside `calculateLayoutImpl`, the cleanup ran with no knowledge of `performLayout`. When the parent's `calculateLayoutImpl` was invoked only with `performLayout=false` (cache miss on measure, cache hit on layout), the cleanup stamped contents children even though the parent itself never had its `hasNewLayout` set.

2. Absolute-layout walk. `layoutAbsoluteDescendants` walks every static layout descendant of the containing block - including ones whose own `calculateLayoutImpl` was skipped via the layout-phase cache. The cleanup invoked along that walk unconditionally stamped contents children, but the parent's `hasNewLayout` was only updated when the recursion actually found new layout downstream.

In both cases, the result is the same invariant violation: a contents node with `hasNewLayout=true` whose parent has `hasNewLayout=false`. A consumer iterating the tree via `hasNewLayout` skips the parent and never clears the stale flag.

X-link: react/yoga#1970

Test Plan:
Added `YGContentsNodeHasNewLayoutTest.cpp` with regression tests:
- `contents_child_hasNewLayout_not_stamped_on_measure_only_visit` - pins the measure-phase fix
- `absolute_descendant_through_contents_is_reachable_via_hasNewLayout` - pins the positive case for absolute-layout path
- `absolute_phase_cleanup_does_not_stamp_when_parent_layout_skipped` - pins the negative case for absolute-layout path

Reviewed By: javache

Differential Revision: D107854528

Pulled By: j-piasecki

fbshipit-source-id: cae5e889622296e8b6380a6428509b5ffea3e9ae
Summary:
## Summary:  Do not synchronize on java.lang.Boolean.

Once JEP 401 is implemented synchronization on
value classes (which box classes are) will throw IdentityException.
In general synchronization on 1) mutable field 2) box class is
inefficient (instances are shared) at best and a bug at worst case
as synchronization is done holding different monitors (it might be
fine, but is hard to reason about).

## Changelog:

[ANDROID] [FIXED] Use explicit `ReactInstanceManager.mHasStartedDestroyingLock` instead of using `ReactInstanceManager.mHasStartedDestroying`

<!-- 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

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

Pull Request resolved: react#56196

Test Plan: GHA

Reviewed By: cortinico

Differential Revision: D110168816

Pulled By: javache

fbshipit-source-id: dae081dc00a94859f19dcc3607971a9c3d6fbd44
Summary:
This fixes an Android Fabric crash in the `overrideBySynchronousMountPropsAtMountingAndroid` path when Native Animated has stored a synchronous `transform` / `opacity` override and a later regular Fabric commit contains `null` for the same prop.

| As-is | To-be |
| --- | --- |
| <img src="https://raw.githubusercontent.com/jingjing2222/react-native-fabric-transform-repro/main/crashed.gif" alt="Baseline Android Fabric transform crash repro" width="320" /> | <img src="https://raw.githubusercontent.com/jingjing2222/react-native-fabric-transform-repro/main/patched.gif" alt="Patched Android Fabric transform result" width="320" /> |
| [crashed.gif](https://github.com/jingjing2222/react-native-fabric-transform-repro/blob/main/crashed.gif) | [patched.gif](https://github.com/jingjing2222/react-native-fabric-transform-repro/blob/main/patched.gif) |

Native Animated can synchronously update `transform` / `opacity` on the UI thread. A regular Fabric commit for the same view may arrive later with stale props, including `transform: null` or `opacity: null`. Those regular Fabric null values should not clear the stored synchronous override, because the override may still represent the fresher Native Animated value.

Before this patch, the override merge path assumed that the incoming Fabric prop had the same non-null type as the stored override. For example, a stored `transform` override is an array, but a regular Fabric update may contain `transform: null`. That mismatch could crash in `SurfaceMountingManager.overridePropsReadableMap`.

This patch:

- Allows regular Fabric `null` updates to be overridden by stored synchronous `transform` / `opacity` values instead of crashing.
- Keeps regular Fabric `transform: null` / `opacity: null` from clearing the stored synchronous override.
- Scopes synchronous null clearing to `transform` / `opacity` only.
- Leaves null values for other props untouched, since other view prop nulls may be meaningful.

This PR intentionally does not change Java Native Animated `restoreDefaultValues()` behavior. That restore implementation can be handled separately because changing it may affect existing apps.

Repro repository:
https://github.com/jingjing2222/react-native-fabric-transform-repro

## Why this is correct

A regular Fabric `null` update is not enough to prove user intent to clear the native animated value, because it can be the stale commit produced after Native Animated already wrote a fresher value on the UI thread. In that case, the stored synchronous override should continue to win.

If the synchronous Native Animated path explicitly sends `transform: null` or `opacity: null`, this patch treats that as a clear signal for that stored override key. The clear behavior is intentionally scoped to the props currently stored by this override path.

```text
regular Fabric null: possible stale commit -> stored synchronous override wins
synchronous transform / opacity null: explicit clear -> stored override key is removed
other null props: left untouched
```

## Changelog:

[ANDROID] [FIXED] - Fix Android Fabric Native Animated crash when regular Fabric null props collide with stored synchronous transform or opacity overrides.

Pull Request resolved: react#56913

Test Plan:
Added regression coverage for stale regular Fabric null commits and scoped synchronous null clears:

- `updateProps_withNullOpacity_keepsStoredSynchronousProp`
- `updateProps_withNullTransform_keepsStoredSynchronousProp`
- `updatePropsSynchronously_withNullOpacity_removesStoredSynchronousProp`
- `updatePropsSynchronously_withNullTransform_removesStoredSynchronousProp`

Ran:

```sh
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.fabric.SurfaceMountingManagerSynchronousMountPropsTest -Preact.internal.useHermesStable=true
```

Result:

```text
BUILD SUCCESSFUL
```

Ran:

```sh
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.animated.NativeAnimatedNodeTraversalTest -Preact.internal.useHermesStable=true
```

Result:

```text
BUILD SUCCESSFUL
```

Ran:

```sh
./gradlew :packages:react-native:ReactAndroid:ktfmtCheck -Preact.internal.useHermesStable=true
```

Result:

```text
BUILD SUCCESSFUL
```

Reviewed By: javache

Differential Revision: D105974289

Pulled By: zeyap

fbshipit-source-id: 7688cfa6b89f2d107c7ae58356864835d41f6add
…#52646)

Summary:
Some third-party libraries, like react-native-reanimated, can clone nodes in a different thread while react-native is calling `setNativeProps_DEPRECATED`. This results in a race condition, where a stale pointer to `nativeProps_DEPRECATED` can be accessed, resulting in a crash. This usually manifests as a `EXC_BAD_ACCESS` crash on iOS. On Android it seems more rare. We've added a lock around accesses to nativeProps_DEPRECATED, but alternative options of fixing this can be considered too.

For more information see software-mansion/react-native-reanimated#7666

[INTERNAL] [FIXED] - Fixed crashes caused by race conditions when third-party libraries clone the shadow dom from a different thread

Pull Request resolved: react#52646

Test Plan:
Due to this being a race condition that only manifests in rare circumstances, it's very difficult to create a reliable reproduction case. The issue mentioned above contains ThreadSanitizer logs that demonstrate this issue. TSan no longer complains with this patch applied, and we've not seen any additional issues from it after deploying it in production over the past week.

Added unit test covering the `nativeProps_DEPRECATED` merge logic in `UIManager::cloneNode` and `ShadowNode::clone`:

```
buck2 test //xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/uimanager:tests -- --regex FabricUIManagerTest
```

Reviewed By: zeyap

Differential Revision: D110169424

Pulled By: javache

fbshipit-source-id: 6139253dcc2c33348a0c1a3bd01e695d15aa83bc
#publish-packages-to-npm&latest
This reverts commit 0a1ebb7.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve the approved Changesets output, native versions, codegen snapshot, and CocoaPods lock. Apply the reviewed changelog correction where applicable.
Preserve validated per-branch source and corrected stack dependencies.
@Saadnajmi Saad Najmi (Saadnajmi) changed the title chore(0.86): merge up to 0.86.0 from upstream branch chore(0.86): prepare stable 0.86.0 with React Native 0.86.3 Sep 22, 2026
Preserve package versions and the linear stack; change only equivalent executable-path metadata.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.
Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.