Summary:
This creates a `debugOptimized` build type for React Native Android, meaning that we can run C++ optimization on the debug build, while still having the debugger enabled. This is aimed at improving the developer experience for folks developing on low-end devices or emulators.
Users that intend to debug can still use the `debug` variant where the full debug symbols are shipped.
## Changelog:
[ANDROID] [ADDED] - Create a debugOptimized buildType for Android
Test Plan:
Tested locally with RNTester by doing:
```
./gradlew installDebugOptimized
```
This is the output of the 3 generated .aar. The size difference is a proof that we're correctly stripping out the C++ debug symbols:
<img width="193" height="54" alt="Screenshot 2025-07-15 at 17 49 50" src="https://github.com/user-attachments/assets/584a0e8d-2d17-40d4-ac29-da09049d6554" />
<img width="235" height="51" alt="Screenshot 2025-07-15 at 17 49 39" src="https://github.com/user-attachments/assets/eda8f9e7-3509-4334-8c16-990e55caa04d" />
<img width="184" height="52" alt="Screenshot 2025-07-15 at 17 49 32" src="https://github.com/user-attachments/assets/a5c94385-bc00-4484-b43e-088ee039827f" />
Rollback Plan:
Reviewed By: cipolleschi
Differential Revision: D78351347
Pulled By: cortinico
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52595
Changelog: [ANDROID][FIXED] Update font scale when recreating `RootView`
At the moment `enableFontScaleChangesUpdatingLayout` flag only works when the activity is configured to handle font scale changes by itself (`configChanges="fontScale"` in the manifest).
When that configuration is missing, the OS handles the font scale changes by recreating the activity, but in this case the path responsible for updating internally kept font size isn't executed.
This diff updates the RootView, so that the display metrics are also updated when it's created. Alternative approach would be to do that on the Activity, but that assumes usage of `ReactActivity`.
Reviewed By: NickGerleman
Differential Revision: D78323174
fbshipit-source-id: e48583091767497b5dfd4f2d938329530de4068d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52668
Changelog: [internal]
These methods have been available for months so no need to consider backwards compatibility with older binaries.
Reviewed By: huntie
Differential Revision: D78412932
fbshipit-source-id: 0f1d541c36c98a4cc8c847d1ee7a08a9d0f4b849
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52678
From partner feedback, there's still appetite to support Node 20.x for the next <1y of life. Lower min version to `20.19.4` (Jul 2025) and widen test matrix in CI.
Changelog:
[General][Breaking] - Our new minimum Node version is Node.js 20 (Overrides #51840)
Reviewed By: cortinico
Differential Revision: D78494491
fbshipit-source-id: c8d9dc6250cb11f8a12ca7e761b65f4a8dae9265
Summary:
In this diff, we migrated IntersectionObserver to tokens: D74262804.
So that we wouldn't have to store shadow nodes on the javascript side.
Storing shadow nodes lead to a memory leak in the past.
Changelog: [internal]
Reviewed By: rubennorte
Differential Revision: D78494075
fbshipit-source-id: 38923ca4b265de6ff81ea20e5649e0bd2e39afc9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52691
Unannotated array literals are unsound in Flow right now. This diff adds in annotations and makes a few things readonly, to reduce future errors.
Changelog: [Internal]
Reviewed By: marcoww6
Differential Revision: D78519638
fbshipit-source-id: d98a7668ecf97bcc87dcb3fad25ade736d885d9a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52686
Enables the `enableVirtualViewRenderState` feature flag by default.
Also, fixed classification for this and the `enableVirtualViewWindowFocusDetection` feature flags. (They were incorrect.)
Changelog:
[Internal]
Reviewed By: lunaleaps
Differential Revision: D78500846
fbshipit-source-id: 099adaa4ed0026c8bb7438df869564d76a999007
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52685
Cleans up the `scheduleAnimatedCleanupInMicrotask ` feature flag and deletes code paths that are now unreachable.
Changelog:
[Internal]
Reviewed By: mdvacca
Differential Revision: D78498600
fbshipit-source-id: 307562030373742e64968ae4c92d6bfbb48ddc71
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52684
Cleans up the `disableInteractionManager` feature flag and deletes code paths that are now unreachable.
Changelog:
[Internal]
Reviewed By: mdvacca
Differential Revision: D78498348
fbshipit-source-id: a3128c1e5ca9c5879080df54b7683a3c916cec13
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52683
Cleans up the `avoidStateUpdateInAnimatedPropsMemo` feature flag and deletes code paths that are now unreachable.
Changelog:
[Internal]
Reviewed By: mdvacca
Differential Revision: D78497862
fbshipit-source-id: 26406e713ca5b7b194159638a20dcfca877ba380
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52625
Changes `react-native/babel-preset` so that by default, `hermes-parser` is configured with `reactRuntimeTarget: "19"`. This changes the compiled output of Component Syntax to not use `forwardRef` when a `ref` prop is present.
Additionally, this adds a new preset option property, `hermesParserOptions`. This object allows users of `react-native/babel-preset` to supply overrides for any `hermes-parser` options.
Changelog:
[General][Changed] - Configures `react-native/babel-preset` to target React 19 by default, meaning Component Syntax will not compile to `forwardRef` calls when a `ref` prop is present.
[General][Added] - Added support to `react-native/babel-preset` for a `hermesParserOptions` option, that expects an object that enables overriding `hermes-parser` options.
Reviewed By: SamChou19815
Differential Revision: D78383269
fbshipit-source-id: 1e6b66b9bfbeaf8a06fdc39031cb6de7e921765f
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52681
Changelog: [internal]
In the original change I made in D78418504 / https://github.com/facebook/react-native/pull/52645 I made 2 mistakes:
1. Used a lock that would try to re-lock on itself without it being recursive (which would cause a deadlock). I didn't see that because when testing I didn't hit the case where we'd exhaust the options.
2. The `attemps` variable wasn't incremented, so we never left the loop in case of exhaustion.
This propagates a flag to `tryCommit` to indicate we've already locked on the commitMutex_ so we don't need to lock again in that case and increases the counter, fixing the issue.
Reviewed By: cortinico
Differential Revision: D78497509
fbshipit-source-id: 546ccd0c84aed5416ce1aef47d79419b4fe06f66
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52680
Changelog: [internal]
Reverting to make the fix easier to pick. Will land again on top.
Original commit changeset: 91d7f5d88a90
Original Phabricator Diff: D78487202
Reviewed By: cortinico
Differential Revision: D78497511
fbshipit-source-id: 58379787786cadcbcbe354feb97bc400a24f9d58
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52679
Changelog: [internal]
Reverting to make the fix easier to pick. Will land again on top.
Original commit changeset: c18e967488de
Original Phabricator Diff: D78480136
Reviewed By: cortinico
Differential Revision: D78497510
fbshipit-source-id: 8037276cb70d27ff695c76cd9575b525568c4489
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52592
Changelog: [Internal] - Expose VirtualViewExperimental in JS, use in a test surface
Reviewed By: yungsters
Differential Revision: D78027899
fbshipit-source-id: d3d9808b8ba8e36c5fdb0c831c0855ed318d0a30
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52590
Changelog: [Internal] - Fix a couple of bugs with VirtualViewExperimental
1. `also` side-effect bug where we were accessing `scrollView` before it was assigned
2. Handling empty `rect`. Now, we don't add the virtualView until it has a non-empty rect layout
Reviewed By: yungsters
Differential Revision: D78287690
fbshipit-source-id: 1806b748a0117e51c7a201191396d79db3a8d205
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52673
We should be incrementing the `attempts` variable as otherwise this loop with never stop.
Created from CodeHub with https://fburl.com/edit-in-codehub
Changelog:
[Internal] -
Reviewed By: rubennorte
Differential Revision: D78487202
fbshipit-source-id: 91d7f5d88a90bdfa806195fd35897f2f51c1deb9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52633
Changelog: [internal]
Now that we have the correct type definition for `console.timeStamp` we can remove the unnecessary `$FlowFixMe` annotations we had to add to use the new arguments.
Reviewed By: hoxyq
Differential Revision: D78405312
fbshipit-source-id: 29378ee6fa5986e22d0dfdfb85b7e25375361dc9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52632
Changelog: [internal]
This improves the type definitions for methods in the global `console` object, most importantly:
- Removes use of `any`.
- Defines correct typing for `console.timeStamp`, including new parameters for the Chrome Extensibility API.
Reviewed By: hoxyq
Differential Revision: D78405314
fbshipit-source-id: 6f31cc3005ff708ef6aa155bcd150d53a845e66c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52631
Changelog: [internal]
Just a small improvement in the type definitions to serve as documentation for the expected arguments for custom tracks in RNDT.
Reviewed By: hoxyq
Differential Revision: D78405313
fbshipit-source-id: 75d250ea27f2e55e172aaf6e72399b85cecd43f4
Summary:
This PR fixes logging of rejections, which stopped working with the transition from using `LogBox` for warnings to directing users to use React Native Debugger, where warnings can be viewed in the `Console` tab.
Rejected promises before this PR used `LogBox.addLog` with the `level: warn` directly without `console.warn`, which notified users to open debugger to view a warning (after rejected promise) without actually printing any warnings to the console.
This PR uses `ExceptionsManager.handleException(error, false /* isFatal */);` for promise rejections that correctly raising an error to the console if needed.
### Rejected Promise in Chrome
Displaying the error as long as it's uncaught in the form:
`Uncaught (in promise) Error`
and if there's a message in that error:
`Uncaught (in promise) Error: ${message}`
once the error is handled, this error disappears:
{F1978806409}
This is done with `Runtime.exceptionThrown`, and `Runtime.exceptionRevoked`:
{F1979815326}
## Changelog:
[General][Breaking] unhandled promises are now handled by ExceptionsManager.handleException, instead of being swallowed as Logbox Warnings.
----
This is a breaking change because we changed the wording for these errors and because some systems (like Sentry) might start monitoring a new set of errors when this code is adopted.
Pull Request resolved: https://github.com/facebook/react-native/pull/51594
Test Plan:
Use `Promise.reject` and observe that the rejection is now shown symbolicated in LogBox and also printed in React Native Debugger Console.
```
<Button
title="Uncaught Promise Rejection"
onPress={() => {
const err = new Error('test error');
err.cause = new Error('cause');
const promise = Promise.resolve().then(() => {
throw err;
// also test with throwing a string / object:
// throw 'aa';
// throw {test: 'object'};
// return Promise.reject();
});
setTimeout(() => {
promise.catch(e => {
console.log('promise error caught', e);
});
}, 4000);
}}
/>
```
### Before
There's no indication whatsoever there's an uncaught promise.
### After
An error is logged:
Error-
{F1979749366}
Text-
{F1979749350}
Object-
{F1979749351}
Promise.reject() or undefined-
{F1979749826}
Reviewed By: hoxyq
Differential Revision: D75442651
Pulled By: vzaidman
fbshipit-source-id: bf6c56e643f03997f5a604b85c543aad62648a29
Summary:
When switching between debug/release we run a small script to make sure to copy the correct version of the RNDeps xcframework.
This script was missing a resolve function that fixed up some path issues that we do when installing in the podspec.
## Changelog:
[IOS] [FIXED] - Fixed issue with RNDeps release/debug switch failing
Pull Request resolved: https://github.com/facebook/react-native/pull/52664
Test Plan:
- Create new RN App
- Install pod with prebuilt deps
- Build (success)
- Switch to release
- Build (success)
Reviewed By: cortinico
Differential Revision: D78481590
Pulled By: cipolleschi
fbshipit-source-id: 2d02b0bc55e8aef6f3fafb4f7aa193c4cf00414e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52662
Changelog: [internal]
In the original change I made in D78418504 / https://github.com/facebook/react-native/pull/52645 I made a mistake and used a lock that would try to re-lock on itself without it being recursive (which would cause a deadlock). I didn't see that because when testing I didn't hit the case where we'd exhaust the options.
This propagates a flag to `tryCommit` to indicate we've already locked on the `commitMutex_` so we don't need to lock again in that case, fixing the issue.
Reviewed By: sammy-SC
Differential Revision: D78480136
fbshipit-source-id: c18e967488de14e73e6abf6f6e82c16bc42a12c6
Summary:
When switching between release/debug we're running a script to copy the correct xcframework. This script for the React-Core prebuilts was not part of the package.json file.
This caused the build to fail after trying to switch from debug -> release.
## Changelog:
[IOS] [FIXED] - Fixed missing script for resolving prebuilt xcframework when switching between release/debug
Pull Request resolved: https://github.com/facebook/react-native/pull/52663
Test Plan:
- Create new RN App
- Install pod with prebuilt deps and core
- Build (success)
- Switch to release
- Build (success)
Reviewed By: cortinico
Differential Revision: D78481302
Pulled By: cipolleschi
fbshipit-source-id: 1c7181e63219098ae140d77ff1cb2c0c9b9642e5
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52661
The CI is currently red on main due to a missing dependency on `rrc_view`
from the recent TransformHelper.cpp addition.
This fixes it.
Changelog:
[Internal] [Changed] -
Reviewed By: cipolleschi
Differential Revision: D78479785
fbshipit-source-id: 3d2b698d9ce46cf22c15ad43005f621526590145
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52660
The documentation for those methods mention that users should override them to
provide their own implementation.
However those vals are not `open` so users cannot really override them.
This fixes it.
See more context on https://github.com/facebook/react-native/pull/48800#issuecomment-3082665024
So this was practically a breaking change, that I'm attempting to mitigate.
Changelog:
[Android] [Fixed] - Make accessors inside HeadlessJsTaskService open again
Reviewed By: cipolleschi
Differential Revision: D78479162
fbshipit-source-id: eefc7332e2004198cd6bd64b60a66215f137ad4a
Summary:
Changelog: [Internal]
Adds a basic `--version` command line flag to the RNDT shell. This will be used in code paths (including tests) that need to verify that the shell is executable, but do not need to actually display a window or hand over control to the main shell instance.
bypass-github-export-checks
Reviewed By: huntie
Differential Revision: D78351936
fbshipit-source-id: e8982cfea6435da0ac9ea5f50d57c7642a8e2edb
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52640
Not having `TransformHelper.cpp` included in CMake is causing the C++ code to fail compiling.
This diff fixes it.
Changelog:
[Internal] [Changed] -
Reviewed By: cipolleschi, javache
Differential Revision: D78414015
fbshipit-source-id: 4900427a86eb38bfec10e5e385296d89c73e9051
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52639
Add feature flag in the attempt to address the pile of tasks reporting the following error in panelapps:
> Error: android_crash:java.lang.AssertionError:com.facebook.react.runtime.ReactHostImpl.onHostPause
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D78339196
fbshipit-source-id: 9ef748e7ea85f179d8f8c418a978bd5c99f70601
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52612
changelog: [internal]
View Culling is purely performance optimisation but it must work correctly with accessibility features like VoiceOver and Switch Control.
In this diff, View Culling is lazily disabled whenever use of an accessibility feature is detected to make sure all views are present in the view hierarchy.
Reviewed By: NickGerleman, philIip
Differential Revision: D78336010
fbshipit-source-id: 7a201afc8e2ffd8b586d75ed4de2c03d7966750c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52604
changelog: [internal]
For Fabric View Culling to work correctly, content offset changes must be applied synchronously to avoid UI flicker.
The flicker happens because content offset update happens asynchronously and the OS paints scroll position update before React Native has a chance to adjust view hierarchy for the new scroll position.
Reviewed By: lenaic
Differential Revision: D78334322
fbshipit-source-id: dc1f1b3f9db9f9547e5a588dc184fcf21cca2727
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52603
Processing transforms is expensive in Java, as it requires bridging the entire ReadableNativeArray/Map. Instead, we can use the existing parser logic `resolveTransform` logic to perform this operation in C++.
Ideally, we actually re-use the existing parsed transform from Props, that could be something we revisit after Props 2.0.
As a follow-up, we should consider also moving the matrix decomposition logic from MatrixMathHelper here, and make that the only information we send back to Java.
Changelog: [Internal]
Reviewed By: NickGerleman
Differential Revision: D78298588
fbshipit-source-id: a698ac8587ccfb2be04665747082398ccdde9294
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52611
We compare the current transform (represented as a ReadableArray) with the incoming one to know whether to invalidate. This can be expensive as it requires to materialize the entire transform data structure over JNI. Instead, we can delegate this comparison to native code, which can compare the underlying folly::dynamic directly.
Changelog: [Internal]
Reviewed By: NickGerleman
Differential Revision: D78340288
fbshipit-source-id: f44a054e234694c316fb080fe2dbc2017780123a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52613
Changelog: [internal]
This adds first-class support for the `detail` field in `performance.mark` and `performance.measure`.
Now that we have access the JS entry in native, we can access the `detail` field to propagate it to DevTools (and use it to extract track names for Perfetto).
In order to avoid the performance overhead of always having to extract the `detail` field from the entry, this is done lazily only if we're actively profiling with DevTools or Perfetto.
Reviewed By: sbuggay
Differential Revision: D78340911
fbshipit-source-id: 383dd1cb6fcc8a04be9e65038503986f196e23c9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52614
Changelog: [internal]
We're adding first-class support for custom tracks, so we can remove the legacy mechanism to specify tracks with the "Tracks:" prefix in the event names.
Reviewed By: sbuggay
Differential Revision: D78340910
fbshipit-source-id: cbbadd519baf7bb50072cb97d8cd1ccc87a8a35c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52588
Changelog: [internal]
This adds tests to show how `performance.measure` isn't spec compliant when `end` and `duration` are used. This will be fixed in the following diff.
Reviewed By: javache
Differential Revision: D78193069
fbshipit-source-id: 30ba4874c4d2b4adb20608fc8d5ed61bfd6d92d8