Pick feature flag to enable experimental MutationObserver (#55919)#56599
Closed
rubennorte wants to merge 45 commits into
Closed
Pick feature flag to enable experimental MutationObserver (#55919)#56599rubennorte wants to merge 45 commits into
rubennorte wants to merge 45 commits into
Conversation
The build_android workflow was incorrectly using for dry-run builds on stable branches (e.g., 0.85-stable), causing it to append suffix to the Hermes version. This resulted in trying to fetch non-existent SNAPSHOT artifacts like in https://github.com/facebook/react-native/actions/runs/22592250332/job/65471130298. This fix adds a check to detect stable branches (via github.ref_name or github.base_ref) and uses instead, which fetches the stable Hermes release from Maven Central without the -SNAPSHOT suffix. We check both github.ref_name and github.base_ref to cover two scenarios: ref_name: Direct pushes to stable branches (e.g. pushing to 0.85-stable) base_ref: Pull requests targeting stable branches (e.g. cherry-pick PRs where the source branch isn't named -stable but the target isChangelog: [Internal]
This reverts commit 111bd59.
This reverts commit 9f335b0.
#publish-packages-to-npm&next
Summary: Pull Request resolved: react#55925 Accidentally clobbered in D93247603. This affects the `fuseboxAssertSingleHostState` feature (react/react-native-devtools-frontend#218). Changelog: [Internal] Reviewed By: vzaidman Differential Revision: D95365621 fbshipit-source-id: 0df7f7bb33bb6bf6eabe15c8ee06c1761567c84b
Summary: Pull Request resolved: react#55613 The cloneMultiple method was written in a way to accept a list of families that are presumed to be owned by the api caller. This designe was mostly aimed at reanimated, that holds refernces to ShadowNodes (that own these families). In the case of AnimationBackend this didn't work properly, as when the view is unmounted we would lose the ShadowNodeFamily shared_ptr that we hold and it could get deallocated. Since now we can get an owning reference to ShadowNodeFamily from ShadowNode::getFamilyShared, we don't have to keep this old unsafe api. Instead we require the caller to have an owning reference with the api itself. This `cloneMultiple` method isn't really adopted in the community, so the breaking change shouldn't be a big problem. Changelog: [General][Breaking] - fix unsafe rawPointer access in cloneMultiple. Reviewed By: zeyap, javache Differential Revision: D93596770 fbshipit-source-id: c4d99b51875968ebce50358c19502cba02c50685
Summary: Pull Request resolved: react#55729 This is added so that one can easily enables c++ AnimatedModule in open source. If an app doesn't use `RCTAnimatedModuleProvider`(ios) or `AnimatedCxxReactPackage`(android), it can fallback to this default AnimatedModule when it has both c++animated and shared backend enabled - shared backend removes the need to pass down start/stop callbacks to NativeAnimatedNodesManagerProvider, so we can cleanly initialize it as static default - RCTAnimatedModuleProvider uses the version of AnimatedModule that still relies on a dedicated CADisplayLink for start/stop - AnimatedCxxReactPackage also bundles internal ViewEventModule (for NativeViewEvents) that shares `NativeAnimatedNodesManagerProvider` with AnimatedModule, but NativeViewEvents is not needed for open source - Alternatively we could also expose `NativeAnimatedNodesManagerProvider` via UIManager so other turbomodules can also use it. However I don't think it makes sense to double down on another animation API on UIManager given we have shared backend. - This assumes DefaultTurboModules is always the fallback module provider. So it'll not override when app already uses RCTAnimatedModuleProvider or AnimatedCxxReactPackage [General] [Added] - Add c++ AnimatedModule to DefaultTurboModules Reviewed By: NickGerleman Differential Revision: D94244698 fbshipit-source-id: 09e905eb4bad7d03cdf87d5b47352060b0e6212f
…into 0.85-stable
#publish-packages-to-npm&next
…t#56005) Summary: Pull Request resolved: react#56005 Changelog: [Internal] The build_debugger_shell CI job was failing because build-binary.js expects pkg.main to start with ./dist/, but without --prepack the prepack.js script never runs, so main stays as ./src/index.js. This was caused by a series of PRs: - PR react#54857 refactored debugger-shell/package.json to use the publishConfig pattern, moving main from ./dist/index.js to ./src/index.js. - PR react#55415 added the --prepack flag to build.js to support this. - PR react#55416 added the build_debugger_shell CI job but ran yarn build without --prepack. The fix passes --prepack to yarn build so that prepack.js rewrites package.json main to ./dist/index.js before build-binary.js runs. Reviewed By: huntie Differential Revision: D95818417 fbshipit-source-id: 03c8340c415960c3937b13bdea3952798d2d420e
Summary: Pull Request resolved: react#56100 ## Changelog: [iOS] [Fixed] - Revert RCTAnimatedModuleProvider change from D94244698 D94244698 added a guard in RCTAnimatedModuleProvider that returns nullptr when useSharedAnimatedBackend() is true, expecting DefaultTurboModules to handle AnimatedModule creation instead. However, on iOS the TurboModule resolution chain in RCTReactNativeFactory delegates to the app-provided getTurboModule:jsInvoker: and returns whatever the delegate returns — even nullptr — without falling through to DefaultTurboModules. This causes `Invariant Violation: Native animated module is not available` on any surface using Animated.View (e.g. Marketplace PDP) when react_fabric.enable_shared_animated_backend_ios is enabled. Revert the RCTAnimatedModuleProvider change from D94244698 so it always provides AnimatedModule when cxxNativeAnimatedEnabled is true, regardless of useSharedAnimatedBackend. The shared backend path in DefaultTurboModules still exists as fallback for non-iOS platforms. Reviewed By: christophpurrer Differential Revision: D96611917 fbshipit-source-id: e01cf5c80dc4cbf30afac6bcf414616c15bfaddb
#publish-packages-to-npm&next
#publish-packages-to-npm&next
#publish-packages-to-npm&next
#publish-packages-to-npm&next
Summary:
When building React.XCFramework we build and link all source files in the XCFramework directly. To avoid Cocoapods to include the same files, we use a Ruby utility function called `podspec_sources` that will emit onlh header files when using (consuming) the build React.XFramework.
When running RN-Tester after building it using the following pod install command line we have effectively linked with the prebuilt XCFrameworks instead of building from source:
`# RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1 RCT_DEPS_VERSION=nightly RCT_TESTONLY_RNCORE_VERSION=nightly bundle exec pod install`
The log in XCode will show an issue with duplciate symbols:
```
oobjc[2551]: Class _TtC10RCTSwiftUI23RCTSwiftUIContainerView is implemented in both xxxx/Library/Develope
r/CoreSimulator/Devices/72157AA1-8D26-424E-8C2E-62D701E70B4A/data/Containers/Bundle/Application/3C711879-443E-48F1-B422-740E7AE82A74/RNTester.app/Frameworks/React.framework/React (0x108d3fb90) and
xxx/Library/Developer/CoreSimulator/Devices/72157AA1-8D26-424E-8C2E-62D701E70B4A/data/Containers/Bundle/Application/3C711879-443E-48F1-B422-740E7AE82A74/RNTester.app/RNTester.debug.dylib
(0x1039ef780). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[2551]: Class _TtC10RCTSwiftUI18ContainerViewModel is implemented in both xxx/Library/Developer/CoreSimulator/Devices/72157AA1-8D26-424E-8C2E-62D701E70B4A/data/Containers/Bundle/Applicatio
n/3C711879-443E-48F1-B422-740E7AE82A74/RNTester.app/Frameworks/React.framework/React (0x108d43b98) and
xxx/Library/Developer/CoreSimulator/Devices/72157AA1-8D26-424E-8C2E-62D701E70B4A/data/Containers/Bundle/Application/3C711879-443E-48F1-B422-740E7AE82A74/RNTester.app/RNTester.debug.dylib
(0x1039f0288). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
```
This is because the RCTSwiftUI.podspec is missing using the `podspec_sources` function when setting up its source files:
```
s.source_files = "*.{h,m,swift}"
```
This will cause Xcode to both link with the XCFramework and compile the sources for this podspec once more - causing an app with duplicate symbols.
After applying this fix, the same test as above shows no duplicate symbols.
## Changelog:
[IOS] [FIXED] - Fixed duplicate symbol error when using React.XCFramework
Pull Request resolved: react#56139
Test Plan:
Run RN-Tester using the following pod install command line, causing us to link with the prebuilt XCFrameworks instead of building from source:
`# RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1 RCT_DEPS_VERSION=nightly RCT_TESTONLY_RNCORE_VERSION=nightly bundle exec pod install`
Build/run the app, observe that the duplicate symbol message is gone.
Reviewed By: alanleedev
Differential Revision: D97317019
Pulled By: cipolleschi
fbshipit-source-id: 032113ad00890f712a6c70c3bd903f545f75aba1
Summary: Follow-up to - react#47033 - react#50431 TODO - [x] bump packages/react-native/third-party-podspecs/fmt.podspec - [x] bump scripts/releases/ios-prebuild/configuration.js - [x] packages/react-native/third-party-podspecs/RCT-Folly.podspec - [x] packages/react-native/gradle/libs.versions.toml - [x] packages/rn-tester/Podfile.lock - rn-rester (main) ios not building on Xcode 26.3, CI currently only supports Xcode 16 - i cannot downgrade macos26.4b4 locally to macos15 to install Xcode16.4 and bump pods this way - so on Xcode 26.3 i've attempted to bump only fmt minimally, ignoring remaining RN 0.86 hashes Ref: https://github.com/search?q=repo%3Afacebook%2Freact-native+%2211.0.2%22&type=code however unable to test rn-tester, ios doesn't seem to build on Xcode 26.3 let alone 26.4b not tested previous versions of Xcode not tested prior branches/tags to main rn-tester CI is passing on old macos-15 Xcode 16.4.0 only, ideally this should be extended to stable macos lts and Xcode 26.3 stable first separate follow-ups to this minimal fmt bump - bump CI macos-15 xcode 16.1-4 to macos-26 xcode 26.0-3 - bump rn-tester Podfile.lock from RN 0.82 to 0.86 main (aka nightly) - bump folly to 2025.11.03.00 - bump folly to 2026.03.09.00 Resolve: react#55601 [General][Changed] Bump fmt to 12.1.0 to fix Xcode 26.4 Pull Request resolved: react#56099 Test Plan: RNTester Reviewed By: alanleedev Differential Revision: D97358194 Pulled By: cipolleschi fbshipit-source-id: 3eb578a99a310e3eb77433692bf35502d0d78d24
#publish-packages-to-npm&next
…eact#56265) Summary: Pull Request resolved: react#56265 When an async void TurboModule method throws an NSException, performVoidMethodInvocation calls convertNSExceptionToJSError which accesses the Hermes JSI runtime from the native method call invoker thread. Since jsi::Runtime is not thread-safe, this causes heap corruption and EXC_BAD_ACCESS crashes across various hermes::vm::* functions. The sibling function performMethodInvocation was already fixed in D71619229 to re-throw the ObjC exception instead of converting to JSError when the call is async. This applies the same fix to performVoidMethodInvocation, which is always async. Related to SEV S641230 (4,550+ Hermes crashes in AMA iOS from OTA bundle 921191722). A JS change behind a QE/MC gate is triggering an NSException in a void TurboModule method for non-employee users, and this bug turns that into widespread memory corruption. This fix prevents the crash, but the triggering diff and throwing TurboModule still need to be identified separately. Matches upstream GitHub issue: https://github.com/facebook/hermes/issues/1957Commits affecting the React Native open source repository must have a changelog entry in the commit summary. Every React Native release has almost 1000 commits, and manually categorizing these commits is very time consuming. --- Changelog: [iOS][Fixed] - Fix Hermes crash when async void TurboModule method throws NSException by re-throwing instead of converting to JSError on wrong thread Reviewed By: javache Differential Revision: D98660782 fbshipit-source-id: bdedc769f17d9aec4156c45d0286c6c31ca006e4
…ct#56151) Summary: When building React Native (`0.85.0-rc.5`) core from source (`RCT_USE_PREBUILT_RNCORE=0`), the `React-Fabric/animated` CocoaPods subspec flattens the `event_drivers/` subdirectory headers because `header_mappings_dir` is not set. CocoaPods' `header_dir` without `header_mappings_dir` places all matched headers directly under the specified directory, losing any subdirectory structure. This means `event_drivers/EventAnimationDriver.h` ends up at `react/renderer/animated/EventAnimationDriver.h` instead of `react/renderer/animated/event_drivers/EventAnimationDriver.h`. The `#include` in `NativeAnimatedNodesManager.h` expects the full path with the `event_drivers/` subdirectory, so the build fails with: ``` 'react/renderer/animated/event_drivers/EventAnimationDriver.h' file not found ``` <img width="1512" height="1012" alt="Screenshot 2026-03-19 at 13 54 29" src="https://github.com/user-attachments/assets/49361c39-d48f-494f-ad7a-c9f3e9749a67" /> This doesn't affect prebuilt (`RCT_USE_PREBUILT_RNCORE=1`) builds because the xcframework ships with a VFS overlay that maps headers correctly. The fix adds `header_mappings_dir` to the `animated` subspec in `React-Fabric.podspec`, which tells CocoaPods to preserve the directory structure relative to `react/renderer/animated`. ## Changelog: [IOS] [FIXED] - Fix `EventAnimationDriver.h` not found when building React Native from source due to missing `header_mappings_dir` in `React-Fabric/animated` podspec Pull Request resolved: react#56151 Test Plan: 1. Set `RCT_USE_PREBUILT_RNCORE=0` in your Podfile 2. Run `pod install` 3. Build the project — previously fails with `'react/renderer/animated/event_drivers/EventAnimationDriver.h' file not found` 4. With this fix, the build succeeds Reviewed By: sammy-SC Differential Revision: D97295771 Pulled By: zeyap fbshipit-source-id: 945fbdeef1d25cedbec1e5b2d60c5a940da85840
…eact#56215) Summary: When testing React Native nightlies, we got the following error from `react-android-0.86.0-nightly-20260325-d1809f0aa-SNAPSHOT-release`: ``` StateWrapperImpl.h:14:10: fatal error: 'react/uimanager/StateWrapper.h' file not found ``` The reason is that build.gradle.kts exports src/main/jni/react/fabric → react/fabric/ in the prefab headers, which includes StateWrapperImpl.h. That header does #include <react/uimanager/StateWrapper.h>, but src/main/jni/react/uimanager is not in the prefab export list — so the header is missing from the AAR. This was introduced in react#55288 where they modified StateWrapperImpl.h to inherit from StateWrapper and added the #include on StateWrapper.h. This has caused Expo's nightlies to break due to the missing header file in the prefabs: - Internally (when RN builds itself): Works fine because all JNI source dirs are on the include path - Externally (when consumers use the published AAR): StateWrapperImpl.h is included in the prefab, it references <react/uimanager/StateWrapper.h>, but that header doesn't exist in the prefab package ## Fix This commit fixes the above problem by including `src/main/jni/react/uimanager` in the prefab. ## Changelog [Internal] - Pull Request resolved: react#56215 Test Plan: I have tested and verified this by running this in the root of the repo: ``` ./gradlew :packages:react-native:ReactAndroid:preparePrefab ls packages/react-native/ReactAndroid/build/prefab-headers/reactnative/react/uimanager/ ``` Before the fix the uimanager folder was not found, with the fix it exists and contains the following files: ComponentNameResolverBinding.h StateWrapper.h UIConstantsProviderBinding.h ## Changelog: [ANDROID] [FIXED] - Fixed missing StateWrapper.h header in prefabs ## Potential Issues There might be an issue with exporting these files in addition to the missing StateWrapper.h - but it seems like this is an issue with other folders in the jni / prefab - everything in a folder is exported when included for prefab. Reviewed By: alanleedev Differential Revision: D98124025 Pulled By: cipolleschi fbshipit-source-id: c8ae35e77652b90477d17ea8cab48ce3ee84d067
#publish-packages-to-npm&next
#publish-packages-to-npm&latest
…hanged outputs (react#55532) Summary: > Side-note: I've been maintaining branches to test these changes for 3 months since around 0.83/0.84, but was waiting for other changes in `scripts/codegen` to stabilise and for 0.84 to land to not interfere with other changes, and to instead target 0.85. Currently, the codegen scripts seem to interfere with Xcode's caching. This can be validated against any app by closing and re-opening Xcode and rebuilding an app that's already been built. Many source files and libraries affected by codegen will start re-building from scratch, skipping the cache. The changes in react@c029032 skip writing to a temporary path and let the codegen script directly write to the output paths, since `moveOutputs` calling `cp` is skipped. However, the codegen scripts still write and copy files to the output directory, even if they exist and haven't changed. This change will replace `writeFileSync` and `cpSync` calls with wrappers that skip writing if the target exists and is identical. ## Changelog: [IOS] [INTERNAL] - Skip writing codegen outputs when outputs are unchanged Pull Request resolved: react#55532 Test Plan: I've been mainly testing this in [`expo/expo`'s `notification-tester`](https://github.com/expo/expo/tree/main/apps/notification-tester) since it's a small app with few dependencies and builds relatively quickly for testing. - Build: etc, `pod install`, `xed ios`, build in Xcode - Rebuild (ground-truth): close and re-open Xcode, build again - Copy new scripts into `node_modules/react-native/scripts/codegen/generate-artifacts-executor` - Rebuild: close and re-open Xcode, build again - Rebuild (2): close and re-open Xcode, build again The re-build timings and target files can then be compared between "Rebuild (ground-truth)" and "Rebuild (2)". The latter will have a very high cache-hit rate and the build completes in about ~10s (instead of ~20s) skipping almost all compilation. I've verified that running `pod install` with the new scripts still works. The re-built files in that case are identical between the old and new scripts. Reviewed By: cortinico Differential Revision: D93099065 Pulled By: cipolleschi fbshipit-source-id: c3da043935d7056990b11204868aaa62ce6b0f7d
Summary: So the formData Upload in fetch is broken on 0.85 on main. I tracked down this PR react#55456 Also reported here react#56404 RCA:- ``` body.isOneShot() body.writeTo(buffer) // This is draining inner file InputStreams ``` Fix is to walk to each children of multipart and check for Oneshot ## 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] - FormData uploads broken in debug builds Pull Request resolved: react#56406 Test Plan: Tested on RN tester <img width="416" height="600" alt="image" src="https://github.com/user-attachments/assets/20cae662-e2ba-4fc7-9f8d-d8e365eb95b2" /> Reviewed By: fabriziocucci, huntie Differential Revision: D100258994 Pulled By: alanleedev fbshipit-source-id: aeda47d45db2152027598c949f0e602a586c4cb3
#publish-packages-to-npm&latest
Summary: Pull Request resolved: react#56401 Add `pushAnimationMutations(Callback)` to the AnimationBackend as a targeted alternative to `trigger()`. The existing `trigger()` method has two problems: 1. **Blast radius**: It calls `onAnimationFrame()` which invokes ALL registered callbacks. When one animation frontend (e.g. Animated) calls `trigger()` in response to an event, every other frontend (e.g. Reanimated) also spins up unnecessarily. 2. **Broken timestamp on iOS**: `trigger()` uses `std::chrono::steady_clock` which on iOS maps to a different kernel clock than what `CADisplayLink` uses for vsync timestamps. These clocks have different baselines and can diverge over time (e.g. after device sleep), causing animations to see time jumps. `pushAnimationMutations(Callback)` fixes both issues: - Executes only the provided callback, not all registered ones - Uses `AnimationChoreographer::now()` which delegates to `HighResTimeStamp`, providing a timestamp from the same clock as the vsync path on each platform Also refactors `onAnimationFrame` to use `unpackMutations`/`applySurfaceUpdates` helpers, avoiding intermediate vector/set merging when accumulating mutations from multiple callbacks. [General][Added] - Add pushAnimationMutations to AnimationBackend for targeted event-driven animation updates Reviewed By: zeyap Differential Revision: D100164749 fbshipit-source-id: 53d36ed316614baa835707a45361ae8f3b828d26
…e possible (react#56465) Summary: Pull Request resolved: react#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
#publish-packages-to-npm&latest
Summary: Pull Request resolved: react#55919 Changelog: [internal] Adds a new feature flag to enable the experimental and partial implementation of `MutationObserver` Reviewed By: Abbondanzo, sammy-SC, javache Differential Revision: D95223862 fbshipit-source-id: e19dd163e5f7fecd9ef28b79be61455f0993a3c4
|
Warning JavaScript API change detected This PR commits an update to
This change was flagged as: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changelog: [internal]
Summary:
This picks #55919 into 0.85-stable, as we'll be testing this feature in apps using 0.85.
Changelog:
Not needed. It's gated behind a feature flag that's disabled by default.
Test Plan:
Tested e2e on Android and iOS using RN Tester. Everything compiles correctly.