Commit Graph
41390 Commits
Author SHA1 Message Date
Christoph Purrer 4bf5575490 Make codegen'd TurboModule event emitters no-op when the emitter callback is absent (#57893)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57893

The codegen'd TurboModule `emitOn<Event>` methods invoked their `EventEmitterCallback` without checking it was set. That callback is installed by the generated `*SpecJSI` constructor, which runs when JS first looks the module up — so a native module that emits before that point invoked an empty `std::function` on iOS (`std::bad_function_call`) or a null field on Android (NPE). Native code commonly holds the module instance and pushes events well before any JS surface mounts, so call sites had to wrap every emit in a try/catch to stay crash-free.

Both generators now read the callback into a local and no-op when it is absent:

- ObjC++ (`serializeEventEmitter.js`): copies `_eventEmitterCallback`, calls it only if non-empty.
- Java (`GenerateModuleJavaSpec.js`): copies the `Nullable CxxCallbackImpl` field and null-checks it.

The local is for readability, not synchronization: the callback is installed once and never cleared, and Java reference reads are already atomic.

The `setEventEmitterCallback` lambdas had a separate lifetime bug: they captured `eventEmitterMap_` by reference and looked events up with `operator[]`. The Java/ObjC module owns the callback and can outlive the C++ `*SpecJSI` that installed it, so a stale callback dereferenced a dangling map; and `operator[]` silently default-inserted a null `shared_ptr` for an unknown event name, which the next line dereferenced. They now capture a copy of the map and use a checked `find` (`serializeModule.js`, `JavaTurboModule.cpp`). Every emitter is registered before the callback is installed, so the copy is complete.

Note the scope of the guarantee: it covers the ObjC++ and Java generators, which route through an `EventEmitterCallback`. A C++-only TurboModule (`<Module>CxxSpec`, from `GenerateModuleH.js`) has no callback to check — it emits through `eventEmitterMap_` entries its own constructor registers — so the "emit unconditionally" guidance is about the callback, not about emitting before construction finishes.

Changelog:
[General][Fixed] - TurboModule event emitters no longer throw when an event is emitted before the emitter callback is installed

Reviewed By: javache

Differential Revision: D115130767

fbshipit-source-id: 7d7b9a706b8983968e3e1207b22c66322f04a223
2026-08-17 10:41:02 -07:00
Gijs Weterings c467843ed0 Fix DOMHighResTimeStamp round-trip truncation in timing primitives (#57975)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57975

`HighResDuration::fromDOMHighResTimeStamp` and `HighResTimeStamp::fromDOMHighResTimeStamp` converted milliseconds back to nanoseconds with `static_cast<int64_t>(units * 1e6)`, which truncates toward zero.

`toDOMHighResTimeStamp()` divides the nanosecond count by 1e6 (one rounding) and multiplying back by 1e6 rounds again, so the product frequently lands a hair below the original integer (e.g. `537648854729249.97`). Truncation then chops off a whole nanosecond, so `fromDOMHighResTimeStamp(toDOMHighResTimeStamp(x)) != x` for roughly 2% of random `now()` values.

That is the source of an intermittent `BridgingTest/highResTimeStampTest` failure, which reported:

```
Expected equality of these values:
  timestamp
    Which is: 8-byte object <22-02 00-21 FD-E8 01-00>
  bridging::fromJs<HighResTimeStamp>( rt, bridging::toJs(rt, timestamp), invoker)
    Which is: 8-byte object <21-02 00-21 FD-E8 01-00>
```

Round to the nearest nanosecond instead of truncating. Nanosecond values below 2^53 are exactly representable in a double, so the round trip is now exact for every value below 2.25e15 ns (26 days of monotonic clock); beyond that the double's ULP exceeds 0.5 ns and residual error is at most 2 ns, which is a floor of the DOM representation itself.

Rounding is also the correct semantic independently of the round trip — truncation gives a systematic downward bias and is asymmetric across zero, which affects the other callers (`RCTHighResTimeStampFromSeconds` for touch timestamps, `RuntimeTargetConsole` `console.timeStamp`, and `PerformanceTracer`).

The rounding is `std::llround`, which costs both overloads their `constexpr`: `<cmath>` rounding functions do not become usable in a constant expression until C++23 (P0533), and this header is compiled as C++20 everywhere (`-std=c++20` in `rn_defs.bzl`, `react-native-flags.cmake`, the podspecs and `Package.swift`). Both carry a `TODO` to restore `constexpr` once the C++23 rollout reaches them.

Dropping it is safe here. All 14 call sites are plain runtime calls — none is in a constant-expression context, none assigns to a `constexpr` variable or feeds a `static_assert` — and both functions are defined inside the class body, so they stay implicitly `inline` and neither linkage nor ABI changes. `fromDOMHighResTimeStamp` converts a `double` arriving from JS, so constant-evaluating it was never meaningful in the first place.

This does narrow the published API surface, so the C++ API snapshots are regenerated: the only change across all nine `.api` files is the `constexpr` keyword dropping off these two declarations, 18 lines in total.

`HighResTimeStamp::fromDOMHighResTimeStamp` now delegates to `HighResDuration`'s so there is a single implementation.

`highResTimeStampTest` previously asserted on `HighResTimeStamp::now()`, whose magnitude is host-uptime-dependent, so it only tripped the bug on about 2% of runs. It now round-trips five fixed nanosecond values (including the exact value from the failing run), which exercises the bug on every run. No test was skipped, disabled, or loosened.

Changelog:
[General][Fixed] - Round instead of truncate when converting a `DOMHighResTimeStamp` back to nanoseconds, so `HighResTimeStamp` and `HighResDuration` round trips are exact

Reviewed By: javache

Differential Revision: D116286868

fbshipit-source-id: 1adafd1b57b1185f51f08fa4dc55d96b88c176cd
2026-08-17 09:21:41 -07:00
Pieter De Baets 88820254e5 Align ref helper flow types (#57850)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57850

React ref callbacks may return only `void` or a cleanup function. Align `TRefCallbackFor` and the related shared callback-ref helpers directly with the core Flow React ref types, then update consumers whose callbacks returned incompatible values. This keeps the contracts canonical and avoids introducing a parallel restricted variant.

Changelog:
[Internal] - Align ref helper types with the React callback contract.

Reviewed By: SamChou19815

Differential Revision: D115064072

fbshipit-source-id: b308ac2b9a453b494c64bdf3d37873b69040ce4c
2026-08-17 08:43:33 -07:00
Gijs Weterings 37dd4044fd Run the ReactAndroid JNI gtests as instrumentation tests (#57976)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57976

The `ReactAndroid` JNI gtests in `react/fabric/test` and `react/jni/test` were configured as plain host C++ tests, but they link against the Android-only JNI libraries. The resulting binary is an Android aarch64 ELF that needs `/system/bin/linker64` and so cannot run on a Linux host:

```
qemu-aarch64: Could not open '/system/bin/linker64': No such file or directory
Test failed to produce the expected output! ... IO error: No result xml files found.
```

They were not failing their assertions — they were never executing. The runner enumerated case names statically out of the binary without running it, so all 6 cases across the two targets were known and reported as failing, with no stack traces at all. The absence of stack traces was itself the tell: the process never started, so no gtest XML was ever produced.

Both targets move to the established pattern for gtests against Android-only native libs: build them as Android instrumentation tests, packaged into an APK and run on a device or emulator.

`FabricMountingManagerTest` can drop its deliberate leak as a result. It previously allocated the manager with a no-op deleter, because `~FabricMountingManager()` calls `jni::ThreadScope::WithClassLoader`, which throws without an attached `JavaVM`. Under instrumentation the gtest runs inside a native method registered via fbjni `makeNativeMethod`, so `cachedOrNull()` is non-null and the closure runs inline — destruction is safe. The fixture now holds a default-constructed (null) `jni::global_ref` member and returns a `std::unique_ptr`; releasing a null `global_ref` is a no-op. All four test bodies are byte-identical. `ModuleRegistryBuilderTest.cpp` is a comment-only correction.

Changelog: [Internal]

Differential Revision: D116286866

fbshipit-source-id: a283deae18e42b0caad330bd3a27307428cfcec4
2026-08-17 05:44:56 -07:00
Rohan Kulkarni 5cb65244dc Fix maintainVisibleContentPosition with rapid data updates (#53542) (#57955)
Summary:
Fixes https://github.com/react/react-native/issues/53542

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

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

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

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

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

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

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

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

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

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

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

Reviewed By: javache

Differential Revision: D115907610

Pulled By: fabriziocucci

fbshipit-source-id: 0cd59b35d7c43803a000b93779cd84c9c4202053
2026-08-17 04:55:47 -07:00
Rob Hogan f63b2a1cb5 Babel preset: Make Platform inlining opt-in via inlinePlatform (default on via @react-native/metro-babel-transformer) (#57973)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57973

`react-native/babel-preset` inlines `Platform.OS` and `Platform.select(...)` whenever it is handed a `platform` (since yesterday - https://github.com/react/react-native/pull/57848 ), but this is over-zealous - `platform` is a pre-existing transform option whose intent is to set the transform target. In some cases (eg, to allow `Platform` mocking from tests), we don't want `Platform` inlining, even though `platform` may already be passed for other reasons.

Gate the inlining behind a separate `inlinePlatform` opt-in, resolved as `options.inlinePlatform ?? babel.caller(...) ?? false`, mirroring how `platform` and `unstable_transformProfile` are already resolved. Metro already models this as a distinct transform option, so both Babel transformers pass it straight through. The caller channel covers the case where the preset is named in a `babel.config.js` and so receives no preset options at all.

Bundling is unaffected: Metro sets `inlinePlatform` on every transform, so `Platform` continues to be inlined through `react-native/metro-babel-transformer`.

Changelog:
[General][Changed] - `Platform.OS` and `Platform.select(...)` inlining in `react-native/babel-preset` now requires the `inlinePlatform` option in addition to `platform`

Reviewed By: GijsWeterings

Differential Revision: D116281656

fbshipit-source-id: 0230cd74f38661862396391da62cf81b34773b85
2026-08-17 04:38:28 -07:00
Evan Katz 376b99ff14 Accept object font variation settings (#57929)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57929

Allow `fontVariationSettings` to accept either the existing CSS-compatible
string or an object keyed by four-character OpenType axis tags. Normalize the
object at the shared style boundary so Text and TextInput retain the existing
native string representation on every platform.

Object serialization is deterministic, supports fractional finite values, and
preserves the current unset versus explicit-clear behavior.

Changelog:
[General][Added] - Add object syntax for `fontVariationSettings`

Reviewed By: Abbondanzo

Differential Revision: D115640672

fbshipit-source-id: e2dbb2498ec213686a3547c8f74c2ade417ef88a
2026-08-16 16:48:16 -07:00
Rob Hogan 40c06121a1 Inline Platform within RN’s Babel preset (#57848)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57848

Adds a React Native-owned Babel plugin that inlines `Platform.OS` and
`Platform.select(...)`, from
`react-native/babel-preset`  at the front of the preset's plugin list (importantly, before
the preset lowers ES modules to CommonJS).

Metro already inlines `Platform`, but its matcher (`metro-transform-plugins`'
`inline-plugin` via `createInlinePlatformChecks`) runs *after* ESM has been
lowered to CommonJS. By then a genuine `import {Platform} from 'react-native'`
has become `_reactNative.Platform.OS` and provenance is obscured and fragile to track. Metro compensates by matching on the local
identifier spelling - so `Platform.OS` inlines whether or not `Platform` is
actually React Native's, and a genuine deep or RN-relative import may be missed entirely.

`Platform` inlining is in any case much more of an RN concern than a Metro one - it has to be aware of RN APIs and module names, and even the module’s path.

This plugin recognises:

- `import {Platform} from 'react-native'` (including aliased imports)
- `import * as RN from 'react-native'`, uses of `RN.Platform`
- `import P from 'react-native/Libraries/Utilities/Platform'`
- the equivalent `require` forms, plus destructuring and immutable aliases
- RN's internal relative imports, e.g. `../../Utilities/Platform`

…and deliberately does *not* recognise anything it cannot prove - a bare
`Platform.OS` global, `React.Platform.OS`, or a same-named import from another
package.

Metro's late matcher is left fully enabled and remains responsible for
those historical forms, so this change is purely additive: it inlines genuine
imports Metro was missing, and changes nothing Metro already handled. Metro’s plugin will be deprecated and removed in future.

Notable details:

- Relative RN imports are resolved lexically, with no filesystem access and no
  platform-extension resolution — the identity we need is the extension-less
  module `<rn-root>/Libraries/Utilities/Platform`, and Metro picks
  `Platform.ios.js` / `Platform.android.js` later. The RN package root is
  identified by directory name, which covers `node_modules/react-native`,
  `packages/react-native` and pnpm layouts alike, and rejects
  `react-native-web` and friends (who would be expected to adjust the paths in their forks)
- Imports are left in place. Removing them would change dependency collection,
  so it is handled separately.
- A no-platform build (`null`, or the empty string that RN's Jest preprocessor
  passes) is a no-op — inlining `Platform.OS` to `""` would be wrong.
- The plugin source is added to the preset's `getCacheKey` so edits invalidate Metro's transform cache.

Changelog:
[General][Changed] - Inline `Platform.OS` and `Platform.select(...)` for
React Native `Platform` imports during the Babel preset, covering some cases that were previously left un-inlined.

Reviewed By: huntie

Differential Revision: D114647943

fbshipit-source-id: b44f38bd22970abba6e7d75c00fdbb27159c17a6
2026-08-16 06:36:58 -07:00
Alex Hunt d07bd6f83a Promote fuseboxFrameRecordingEnabled to canary (#57953)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57953

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D111901168

fbshipit-source-id: 90f8b0432fbec5b144fa4e0fa9e7bd4ad12ce445
2026-08-14 07:54:22 -07:00
Alex Hunt b74adf051f Add idle frame support to Performance timeline (#57952)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57952

Implement Idle frame spans in React Native DevTools, by emitting synthetic `NeedsBeginFrameChanged` + `BeginFrame` events.

**Definition**

An idle frame is emitted whenever the gap between two consecutive frames exceeds one vsync interval, derived from the display's refresh rate (`CADisplayLink.duration` on iOS, `Display.refreshRate` on Android, falling back to 60 Hz).

```
   frame N                  gap > 1 vsync                 frame N+1
+------------+  +--------------------------------+  +------------+
| BeginFrame |  | NeedsBeginFrameChanged         |  | BeginFrame |
| DrawFrame  |  | BeginFrame     (no DrawFrame)  |  | DrawFrame  |
+------------+  +--------------------------------+  +------------+
                    rendered as an "Idle frame"
```

**Implementation notes**

- Drop frames that begin before the recording start — Android `FrameMetrics` can deliver frames from app startup, and the first iOS `CADisplayLink` callback reports the previous vsync.
- Sort frames by begin timestamp before serializing, since async screenshot encoding can deliver them out of order and break gap detection.
- iOS: skip the frame event when the screenshot is unchanged, letting the gap render as an idle frame.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D97502569

fbshipit-source-id: 7cb19e0a462ad878f0b44b66f6b5de3f76426ffe
2026-08-14 07:54:22 -07:00
Nycollas ead93778a1 Fix Hermes bytecode version mismatch in SwiftPM Release builds (#57928)
Summary:
`react-native spm add`'s Release builds crash on launch with:

```
Compiling JS failed: Wrong bytecode version. Expected 99 but got 98
```

This happens because the SwiftPM integration resolves the Hermes **runtime**
(the downloaded `hermes-engine.xcframework`) and the Hermes **compiler** (the
`hermesc` binary that turns the JS bundle into bytecode) from two independent,
unsynced sources:

- `download-spm-artifacts.js`'s `resolveHermesArtifact()` picked the runtime
  by querying the `hermes-compiler` package's `latest-v1` dist-tag on the npm
  registry **live, at build time**.
- `generate-spm-xcodeproj.js`'s `resolveHermesCliPathSetting()` (and
  `react-native-xcode.sh`, for the CocoaPods-free fallback) points
  `HERMES_CLI_PATH` at the `hermes-compiler` package **already installed in
  this project's own `node_modules`** — whatever got pinned the last time
  `npm install` ran.

If the `latest-v1` dist-tag advances on npm between `npm install` and the
Release build (which happens routinely as new Hermes builds are published),
the downloaded VM and the locally pinned `hermesc` fall out of sync and the
app crashes at launch. `react-native-xcode.sh` already documents this exact
invariant ("react native pins the hermes-compiler version, so the compiler's
bytecode version always matches the prebuilt hermes VM artifacts") — SwiftPM's
artifact download just wasn't honoring it.

This PR makes `resolveHermesArtifact()` read the pinned `hermes-compiler`
version from `node_modules` first (the same `require.resolve` lookup already
used for `HERMES_CLI_PATH`), so the runtime download and the compiler always
agree. It falls back to the previous `latest-v1` npm lookup only when
`hermes-compiler` isn't locally resolvable (e.g. `USE_HERMES=false` apps that
never installed it). Explicit `HERMES_VERSION` overrides (`nightly`,
`latest-v1`, a literal version) are unchanged.

Fixes https://github.com/react/react-native/issues/57917.

## Changelog:

[IOS] [FIXED] - Fix Hermes runtime/compiler version mismatch causing "Wrong bytecode version" crashes in SwiftPM Release builds

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

Test Plan:
Added unit tests covering the new local-resolution path, the fallback when
`hermes-compiler` isn't installed, and confirming existing `HERMES_VERSION`
overrides still take precedence over the local pin.

```
$ node_modules/.bin/jest packages/react-native/scripts/spm/__tests__/download-spm-artifacts-test.js
Test Suites: 1 passed, 1 total
Tests:       70 passed, 70 total

$ node_modules/.bin/flow check packages/react-native/scripts/spm/download-spm-artifacts.js
No errors!

$ node_modules/.bin/eslint packages/react-native/scripts/spm/download-spm-artifacts.js packages/react-native/scripts/spm/__tests__/download-spm-artifacts-test.js
(no output — clean)

$ node_modules/.bin/prettier --check packages/react-native/scripts/spm/download-spm-artifacts.js packages/react-native/scripts/spm/__tests__/download-spm-artifacts-test.js
All matched files use Prettier code style!
```

Reproduced the crash and confirmed the fix end-to-end using the public
reproducer linked from the issue
(https://github.com/marandaneto/react-native-087-swiftpm-hermes-bytecode-repro):

- Before the fix: `npm run reproduce` builds successfully but launching the
  app in the iOS Simulator crashes with `Compiling JS failed: Wrong bytecode
  version. Expected 99 but got 98`.
- After applying the equivalent fix to the reproducer's installed
  `react-native` copy: the log shows `Using locally pinned hermes-compiler:
  250829098.0.16`, and both the debug and release Hermes runtime artifacts
  resolve to that exact version — matching the `hermesc` used for
  `HERMES_CLI_PATH`. `xcodebuild ... -configuration Release` succeeds, and
  the app installs and launches cleanly on an iPhone 17 Pro (iOS 26.5)
  simulator with no crash.

Reviewed By: cortinico

Differential Revision: D115859923

Pulled By: cipolleschi

fbshipit-source-id: 1b65a7aa28f502374a3553c1849b8ff29b5afd10
2026-08-14 07:12:17 -07:00
Sam Zhou 88043334e3 Remove unused babel-plugin-syntax-hermes-parser (#57958)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57958

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D115933669

fbshipit-source-id: beb16a462472effcdcc2f9aea3d1baae5fd075b8
2026-08-13 17:58:27 -07:00
Dongda Li 1291d7ce8e fix(ios): make the unmountChildComponentView assert message bounds-safe (#57865)
Summary:
`-[RCTViewComponentView unmountChildComponentView:index:]` bounds-checks the `RCTAssert` *condition*, but the failure message it formats afterwards calls `-objectAtIndex:` on the same out-of-range `index`:

```objc
RCTAssert(
    (self.currentContainerView.subviews.count > index) &&              // guarded
        [self.currentContainerView.subviews objectAtIndex:index] == childComponentView,
    @"... tag at index: %@)", ...,
    @([[self.currentContainerView.subviews objectAtIndex:index] tag]));  // not guarded
```

So the exact situation the assert exists to report — a shadow-tree/native child-index mismatch — raises `NSRangeException` *while being reported*, instead of being reported.

That is normally invisible, because a source Release build strips `RCTAssert` and the mismatch is harmless: `index` is used only inside the asserts, and the real work, `[childComponentView removeFromSuperview]`, never needed it. But the prebuilt `React.framework` published to Maven Central is built with assertions enabled (https://github.com/react/react-native/issues/57454), so this is live in App Store builds — we hit it on RN 0.81.5 via Expo SDK 54, symbolicated against the published `reactnative-core-dSYM-release` artifact:

```
NSRangeException: *** -[__NSArrayM objectAtIndex:]: index 13 beyond bounds [0 .. 8]
  -[RCTViewComponentView unmountChildComponentView:index:]  (RCTViewComponentView.mm:163)
  RCTPerformMountInstructions(...)                          (RCTMountingManager.mm:97)
  -[RCTMountingManager performTransaction:]                 (RCTMountingManager.mm:258)
  -[RCTMountingManager initiateTransaction:]                (RCTMountingManager.mm:247)
```

This is the second of the two fixes suggested in https://github.com/react/react-native/issues/57454 and stands on its own for any build with assertions enabled.

The change also reads `self.currentContainerView` once instead of four times. That getter is not a plain accessor — it creates or tears down `_containerView` and reparents subviews — so re-invoking it inside an assert's arguments is worth avoiding regardless.

The hoisted locals and the assert sit inside `#ifndef NS_BLOCK_ASSERTIONS`, matching the existing guard at `RCTViewComponentView.mm:335`. Without it the locals are unused once assertions are compiled out, which is a `-Werror,-Wunused-variable` build failure, and the hoist would otherwise make that side-effecting getter run on every unmount in a Release build where it previously did not run at all. With the guard it is read once per unmount in Debug and not at all in Release.

## Changelog:

[IOS] [FIXED] - Report a `RCTViewComponentView` child-index mismatch instead of raising `NSRangeException` while formatting the assert message

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

Test Plan:
I don't have a macOS build environment, so I have not compiled this — flagging that plainly. What backs the change:

- Five App Store crash reports (RN 0.81.5, iOS 26.5.2 / 26.6, three device models) all symbolicate to the message argument on this line, never to the guarded condition.
- `strings` on `react-native-artifacts-0.81.5-reactnative-core-release.tar.gz` shows both `Attempt to unmount…` format strings present, confirming the call sites are compiled into the release artifact — same check https://github.com/react/react-native/issues/57454 reports for 0.85.3 and 0.86.0, so the artifact defect reaches at least as far back as 0.81.
- Behaviour is unchanged whenever the assert passes; when it fails, the message now prints `out of bounds` in place of a tag that cannot be read.

Happy to rework this if you would rather the assert drop the `tag at index` field entirely, or if fixing the artifact build flags is considered sufficient on its own.

## Added on import: build, tests, and answers to the open questions

Compiled and tested, which the author could not do.

```
buck2 test fbsource//xplat/js/react-native-github:MountingTestsApple
→ Pass 19. Fail 0.
```

Adds `React/Tests/Mounting/RCTViewComponentViewUnmountTests.mm`, picked up by the existing `MountingTestsApple` glob. Restoring the pre-fix `RCTViewComponentView.mm` and re-running fails exactly the out-of-bounds case:

```
✗ RCTViewComponentViewUnmountTests/testUnmountWithOutOfBoundsIndexReportsRatherThanRaisingRangeException
Tests finished: Pass 18. Fail 1.
```

The second case, `testUnmountWithInBoundsMismatchStillReportsTagAtIndex`, passes against both old and new code on purpose: it pins that the in-bounds mismatch path still reports the real tag rather than the new `out of bounds` placeholder.

### Why the test is shaped the way it is

Two non-obvious constraints, both of which broke a more natural first attempt:

1. `RCT_NSASSERT` is defined as `RCT_DEBUG`, so in a debug build a failing `RCTAssert` calls the custom handler **and then** raises through `NSAssertionHandler`. Every failing assert throws, fixed or not, so `XCTAssertNoThrow` cannot be the assertion. The discriminator is that pre-fix the message arguments raise `NSRangeException` at the call site *before* `_RCTAssertFormat` runs, so the handler never fires at all. The test asserts the handler ran and that whatever escaped was not `NSRangeException`.
2. `RCTPerformBlockWithAssertFunction` calls `block()` between pushing and popping its handler with no `try`/`finally`, so an exception escaping the block leaks the handler into every later test in the process. The raise is therefore caught inside the block.

### Other checks

- `index` is `NSInteger` (`RCTComponentViewProtocol.h:64`), so the added `index >= 0` is meaningful rather than tautological. The previous `count > index` relied on a negative index promoting to a large `NSUInteger` and failing the unsigned comparison, which was correct by accident.
- The `NSNumber *` / `NSString *` ternary in the message compiles without warning.
- `arc lint -e extra` on the new test reports only a `NULLSAFECLANG` infrastructure failure that self-identifies as "not a code issue". The 55 pre-existing CLANGTIDY warnings in `RCTViewComponentView.mm` are untouched and are not attributed to this diff.

### NOTE: on the author's two questions

**Is fixing the artifact build flags sufficient on its own?** No. https://github.com/react/react-native/issues/57454 is the right root-cause fix and should still happen, but this change is worth having independently: the assert is broken *as an assert*. In any build where assertions are compiled in, including local Debug, the assert that exists to report an index mismatch raises while reporting it, so the diagnostic is unavailable exactly when it is needed. Fixing the artifact flags would hide that from production without repairing it.

**Should the `tag at index` field be dropped instead?** Recommend keeping it. It is the field that tells you which view actually occupies the slot, which is the useful part of the diagnostic, and the second test above locks in that it still appears when the index is in bounds.

### Release-build guard (added after the first sanity-check failure)

The first import version failed the sanity check with:

```
error: unused variable 'isIndexInBounds' [-Werror,-Wunused-variable]
```

`NS_BLOCK_ASSERTIONS` makes `RCTAssert` expand to `do {} while(false)`, so with assertions compiled out the hoisted locals have no remaining use. The hoisted lines and the assert are now wrapped in `#ifndef NS_BLOCK_ASSERTIONS`, which is the idiom this same file already uses at `RCTViewComponentView.mm:335` for a local pulled out of an assert.

That also restores a property the hoist had quietly removed. Before this diff the four `self.currentContainerView` reads sat inside the macro arguments and disappeared entirely in a Release build. Hoisting them out made the getter run on every unmount in Release, and that getter is not a plain accessor: it can allocate `_containerView`, reparent every subview into it and move `clipsToBounds` and `layer.mask`, or in the other branch tear the container down and nil it. With the guard the getter is read once per unmount in Debug and not at all in Release, which is better than both the original and the unguarded version.

Verified locally by defining `NS_BLOCK_ASSERTIONS` at the top of the file to simulate a Release build, against `RCTFabricComponentViewsBaseApple`, which is the target that owns this file:

| State | Result |
|---|---|
| Unguarded, assertions off | `error: unused variable 'isIndexInBounds'`, BUILD FAILED |
| Guarded, assertions off | exit 0 |
| Guarded, assertions on (debug) | Pass 19. Fail 0. |

Reviewed By: christophpurrer

Differential Revision: D115424016

Pulled By: fabriziocucci

fbshipit-source-id: b825f145c1867a230c0c6cd12a41950a83468ed2
2026-08-13 12:51:39 -07:00
bintangakbarRK e0aa7a8b0a Fix keyboard inset state across ScrollView recycling (#57811)
Summary:
Closes https://github.com/react/react-native/issues/57755.

`RCTScrollViewComponentView` remained subscribed to keyboard notifications while pooled with `_automaticallyAdjustKeyboardInsets` still enabled. A late notification could therefore restore keyboard insets after `prepareForRecycle` had cleared them.

Disarm keyboard inset adjustment during recycling, then always synchronize the flag from the incoming props so a recycled view is correctly re-armed when the next ScrollView opts in.

## Changelog:

[IOS] [FIXED] - Prevent recycled ScrollViews from retaining automatic keyboard inset behavior.

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

Test Plan:
- Added `RCTScrollViewComponentViewTests.testAutomaticallyAdjustKeyboardInsetsAcrossRecycling`, covering enabled behavior, ignored keyboard notifications while recycled, and re-enabling after remount.
- `/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang-format --dry-run --Werror packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm packages/react-native/React/Tests/Mounting/RCTScrollViewComponentViewTests.mm`
- `git diff --check`

The full native XCTest suite was not run locally because this sparse checkout does not include a bootstrapped RNTester/CocoaPods workspace.

Reviewed By: christophpurrer

Differential Revision: D114719614

Pulled By: fabriziocucci

fbshipit-source-id: e8e035fe8a74909b2281fc8d52af0e034f2bafe4
2026-08-13 12:48:48 -07:00
Sam Zhou 704c2b1954 Bump flow-{estree,parser,eslint,transform,api-translator} to latest (#57932)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57932

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D115802149

fbshipit-source-id: aa4c730e47ab9b362f7a6e1a16c8127117b09c08
2026-08-13 12:21:06 -07:00
Peter Abbondanzo 579aedcbd5 Add TextInput placeholder screenshot coverage (#57925)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57925

Add RNTester screenshot coverage for single-line and multiline `TextInput` placeholders on Android and iOS. The test verifies that a long single-line placeholder is ellipsized while a multiline placeholder wraps.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D115731487

fbshipit-source-id: bf13562b181f9c104056638c7cfa1d57416a3364
2026-08-13 11:48:22 -07:00
Alex Hunt 8a7dfce604 Update debugger-frontend from 571dc30...dbc1c52 (#57954)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57954

Changelog: [Internal] - Update `react-native/debugger-frontend` from 571dc30...dbc1c52

Resyncs `react-native/debugger-frontend` from GitHub - see `rn-chrome-devtools-frontend` [changelog](https://github.com/react/react-native-devtools-frontend/compare/571dc30a5de05c09d6734fd38f6a6c279d5d7ec2...dbc1c525fbe78bf415ff5441ea05d5b2475b2c24).

### Changelog

| Commit | Author | Date/Time | Subject |
| ------ | ------ | --------- | ------- |
| [dbc1c525f](https://github.com/react/react-native-devtools-frontend/commit/dbc1c525f) | Alex Hunt (hello@alexhunt.dev) | 2026-08-13T17:58:45+01:00 | [Enable "Capture screenshot" command for React Native targets (#252)](https://github.com/react/react-native-devtools-frontend/commit/dbc1c525f) |
| [e06f16d4e](https://github.com/react/react-native-devtools-frontend/commit/e06f16d4e) | Nicola Corti (corti.nico@gmail.com) | 2026-06-10T14:11:47+01:00 | [Bump remaining vulnerable dev dependencies (#260)](https://github.com/react/react-native-devtools-frontend/commit/e06f16d4e) |
| [950f4a8e3](https://github.com/react/react-native-devtools-frontend/commit/950f4a8e3) | Nicola Corti (corti.nico@gmail.com) | 2026-06-04T14:46:30+01:00 | [Bump vulnerable dev dependencies (#259)](https://github.com/react/react-native-devtools-frontend/commit/950f4a8e3) |
| [af53aca17](https://github.com/react/react-native-devtools-frontend/commit/af53aca17) | Alex Hunt (hello@alexhunt.dev) | 2026-04-20T15:00:21+01:00 | [Disable inapplicable commands for React Native targets (#251)](https://github.com/react/react-native-devtools-frontend/commit/af53aca17) |

Reviewed By: hoxyq

Differential Revision: D115891642

fbshipit-source-id: fcf1353aa4a4f45fe246fbc1ac6afa6837213ae1
2026-08-13 10:37:36 -07:00
riteshshukla04 092734772a perf: Cache normalisedColors output (#57896)
Summary:
While looking into something I saw this processColor function , for every color we  are calculating normalise Color even though it would have been done earlier.
This is a simple approach. Maybe we can add things like LRU. With some simple scripts(Rendering around 1000 cells) I found around 13% faster .
## 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
-->
[GENERAL][FIXED] - use cached results for already normalised colors

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

Test Plan: Tested in RN tester.

Reviewed By: christophpurrer

Differential Revision: D115779590

Pulled By: Abbondanzo

fbshipit-source-id: a915bc641fbaff1055c18ac1efa20552a725102f
2026-08-13 08:59:46 -07:00
Riccardo Cipolleschi bc35168d1b Back out "Add Maestro Cloud CI for RNTester" (#57948)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57948

Original commit changeset: 20a5feb21ec1

Original Phabricator Diff: D115732295

## Changelog:
[Internal] -

Reviewed By: cortinico

Differential Revision: D115880038

fbshipit-source-id: c3ccc0f46be029ec13866465df02d73d3b36413e
2026-08-13 08:33:30 -07:00
Riccardo Cipolleschi 789e54c827 Back out "Fix Maestro Cloud project ID reference" (#57947)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57947

Original commit changeset: f7475fa8fcd3

Original Phabricator Diff: D115871650

## Changelog:
[Internal] -

Reviewed By: cortinico

Differential Revision: D115880037

fbshipit-source-id: 0d4e121e37d087e94fa0e47642cd4fd8c3e07309
2026-08-13 08:33:30 -07:00
Dawid Małecki b7f0baf8f9 Emit a real framework for React-cxxstableapi under use_frameworks! (#57936)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57936

`react/cxxstableapi` is a header-only module — the stable API guards are pure
preprocessor headers with no compilable source. Under `use_frameworks!`,
CocoaPods emits a `PBXAggregateTarget` for a pod with no compilable sources, and
an aggregate target produces no `.framework`, so pods depending on
`React-cxxstableapi` cannot resolve the guard headers.

Add an anchor translation unit so the pod has one source and CocoaPods emits a
real framework target instead, and widen the podspec's build-from-source glob to
pick it up. The prebuilt glob stays headers-only, since prebuilt pods do not
generate frameworks. This mirrors the existing `CSSDummy.cpp` anchor for the
header-only `React-renderercss` pod.

Also register `react/cxxstableapi` as a subdirectory of the Fantom tester CMake
build so the guard headers resolve there.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D115859623

fbshipit-source-id: 47e63560e1478ad507d1f28f053b925438232ea4
2026-08-13 08:20:05 -07:00
Dawid Małecki a9df3d5408 Define RN_BUILDING for React Native's own CMake, SwiftPM, and Buck targets (#57861)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57861

React Native's public C++ headers are gaining guards from `react/cxxstableapi`, which
turn a direct include of a fine-grained header into an error for consumers that opt into
the strict API by defining `RN_STRICT_API`. React Native's own sources keep including
those headers directly, so they are exempted via `RN_BUILDING`.

Unlike CocoaPods, these three build systems each have a single chokepoint:

- CMake: one `add_compile_definitions(RN_BUILDING)` in the ReactAndroid JNI project,
  a directory property inherited by every `add_react_common_subdir` below it. It is
  declared *after* the third-party NDK subdirectories so glog/boost/folly/fmt never see
  it, and this project never compiles app or third-party module code.
- SwiftPM: one `.define` in the shared `Target.reactNativeTarget` factory that every
  React Native target is created through. `cxxSettings` are per-target and are not
  inherited by packages that depend on React.
- Buck: a `_set_rn_building_flag` helper called from the four macros React Native's own
  targets use. It is `preprocessor_flags`, deliberately
  not `exported_preprocessor_flags`, so dependents are not exempted either.

This change is inert on its own: nothing behaves differently unless a consumer defines
`RN_STRICT_API`.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D115051088

fbshipit-source-id: 70b525a7291227a4400beefdba2b0a3571dc032c
2026-08-13 08:20:05 -07:00
Alex Hunt 2e4e8303ea Update agent guidance, move to AGENTS.md (#57944)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57944

The V1 of our `CLAUDE.md` was mostly contributor boilerplate. Revise this towards a plan overview of the repo — giving the agent immediate context on working in the codebase (and reducing exploratory file reads).

Also moves `CLAUDE.md` to `AGENTS.md`, for interop with non-Claude harnesses — `CLAUDE.md` is now a pointer to this source.

New contents:

- Repo structure
- Common commands
- Gotchas
- Contributing guidelines

This remains intentionally high level rather than exhaustive, to keep the context window lean. We can move towards nested `AGENTS.md` files over time.

**Notes**

- `CONTRIBUTING.md` is unchanged — already a short pointer to reactnative.dev. (Possible candidate for later deletion.)

Changelog: [Internal]

Reviewed By: Abbondanzo

Differential Revision: D115564651

fbshipit-source-id: 8e237cd1ab6189632bf59b2bd865c5f06fef8bcc
2026-08-13 07:20:06 -07:00
Nicola Corti 9c770f5718 Fix Maestro Cloud project ID reference (#57943)
Summary:
- read the Maestro Cloud project ID from the repository secret in both iOS and Android jobs
- match the existing repository configuration and unblock input validation

The failing main run resolved vars.MAESTRO_CLOUD_PROJECT_ID to an empty string because MAESTRO_CLOUD_PROJECT_ID is configured as a GitHub Actions secret.

Changelog:
[Internal] [Changed] -

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

Test Plan:
- node_modules/.bin/prettier --check .github/workflows/test-all.yml
- git diff --check

Reviewed By: huntie

Differential Revision: D115871650

Pulled By: cortinico

fbshipit-source-id: f7475fa8fcd30e334b9bf3d361f6f718bd0ca7e4
2026-08-13 07:11:06 -07:00
generatedunixname910664361436750 b80bc19dc7 Fix CQS signal facebook-hte-BadImplicitCast in xplat/jsi/jsi/test (#57942)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57942

Reviewed By: Daniel9z

Differential Revision: D115846369

fbshipit-source-id: f28285263cd970cfb88c9d3aa5c4428e97bd3206
2026-08-13 07:10:39 -07:00
Riccardo Cipolleschi e334b9318d Wait for images before box-shadow screenshots (#57922)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57922

Changelog: [Internal]

Expose the box-shadow example test identifier only after all three images have loaded. The E2E navigation helper now waits for stable image content before capturing the screenshot, and the Nougat golden reflects the complete example.

Reviewed By: Abbondanzo

Differential Revision: D115740465

fbshipit-source-id: 78bbec4ef20ce14832ec423c5e98320eb3ba34a0
2026-08-13 06:59:30 -07:00
Riccardo Cipolleschi 1c4a46f4e3 Ignore stale minimum-view-time viewability updates (#57923)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57923

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

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

Reviewed By: Abbondanzo

Differential Revision: D115740467

fbshipit-source-id: 0a308dbc57c1d1fc5b2b669d998d1d9f8f1495f1
2026-08-13 06:59:30 -07:00
Riccardo Cipolleschi e774f0d623 Stabilize sampling-profiler tracing test (#57924)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57924

Changelog: [Internal]

Exercise JavaScript briefly before ending each trace. This gives the sampling profiler a bounded opportunity to record a stack while preserving the test comparison between disabled and enabled categories.

Reviewed By: Abbondanzo

Differential Revision: D115740464

fbshipit-source-id: 9aa42ccf597aa9198cb31c2dae601f1709506d24
2026-08-13 06:59:30 -07:00
Andrew Ghostuhin 551d12a787 Fix Android inline Text views with small font scale
Summary:
Fixes https://github.com/facebook/react-native/issues/50916.
Closes torin-asakura/workspace#126.

Android inline views inside `<Text>` receive their measured layout size from Fabric as layout units/DIP. TextLayoutManager was converting those attachment dimensions with `PixelUtil.toPixelFromSP(...)`, so a device font scale below 1.0 shrank the inline view placeholder width. In the https://github.com/facebook/react-native/issues/50916 RNTester reproducer, a measured `Row cutoff` attachment around 155px became about 132px at `font_scale=0.85`, clipping the rendered text to `Row`.

This changes inline text attachment dimensions to use DIP conversion and rounds them up to the pixel grid in both spannable construction paths.

## Changelog:

[ANDROID] [FIXED] - Keep inline views inside Text from shrinking with Android system font scale

X-link: https://github.com/facebook/react-native/pull/57132

Reviewed By: christophpurrer

Differential Revision: D108030457

Pulled By: cipolleschi

fbshipit-source-id: af68489aed0ee9c39f3a440f07ca9286ff5ed30c
2026-08-13 04:51:25 -07:00
Rob Hogan 2b995be464 Make BabelNode* types module-local within @babel/types (remove ambient globals) (#57866)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57866

Now that all internal and OSS Babel types use explicitly imported types (see stack), modify our Babel type generator scripts and the generated lib defs so that they no longer declare global types.

This unblocks migrating to a modern `flowtyped` declaration and removing the `.flowconfig` coupling.

Changelog: [Internal]

Reviewed By: huntie

Differential Revision: D114881982

fbshipit-source-id: df29b8e22cf070f2e39c994f3a0856be4939fdc9
2026-08-13 04:49:31 -07:00
Radosław Rolka 4433cdbe62 Set SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG when injecting SPM (#57914)
Summary:
Swift's `#if DEBUG` is gated by SWIFT_ACTIVE_COMPILATION_CONDITIONS, not by GCC_PREPROCESSOR_DEFINITIONS (which only reaches C/ObjC/C++). The app template does not commit that setting; CocoaPods injects it at `pod install` time (react_native_post_install -> set_build_setting
SWIFT_ACTIVE_COMPILATION_CONDITIONS = ["$(inherited)", "DEBUG"] on Debug).

An app set up with the experimental SwiftPM support never runs CocoaPods, so `#if DEBUG` is false even in a Debug build: AppDelegate.swift's `bundleURL()` skips the Metro URL and falls back to a main.jsbundle a Debug build never produced, and the app dies at launch with "No script url provided ... unsanitizedScriptURLString = (null)" while Metro is running.

Info: https://github.com/react-native-community/template/pull/244

## Changelog:

Inject the setting from `spm add`/`update` alongside the other React build settings, into debug-flavored configurations only (the same flavorForBuildConfiguration test that selects the debug xcframeworks), so a config linking the debug binaries also compiles its Swift with DEBUG.

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[IOS] [FIXED] - Set SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG when injecting SPM

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

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

Test Plan:
1. Build spm-only rn app in debug
    - App will fail to connect to the Metro
2. Apply changes and run `react-native spm`
3. Build again
    - App will work as expected in debug and Metro will be connected

Reviewed By: Abbondanzo

Differential Revision: D115736551

Pulled By: cipolleschi

fbshipit-source-id: 1e42ca26ac1992bfa827ce85a63cf4564d313e15
2026-08-13 03:55:48 -07:00
Aravind M Nair a4733b1ca1 Fix crash when accessibilityRole="tabbar" is used on Android (#57915)
Summary:
Fixes https://github.com/react/react-native/issues/57890.

`tabbar` is part of the public `AccessibilityRole` union in both Flow and TypeScript, with nothing marking it iOS-only, and on iOS it maps to `UIAccessibilityTraitTabBar`. On Android the `AccessibilityRole` enum has no `TABBAR` entry, so `fromValue()` throws `IllegalArgumentException` from `BaseViewManager.setAccessibilityRole` during `createViewInstance` and the app crashes on mount. It is the only value in the union Android fails to resolve.

This adds `TABBAR` to the enum and maps it to `android.view.View` in `getValue`, next to `TAB` and `TABLIST`, which likewise have no dedicated Android widget. `getValue` is an exhaustive `when` with no `else`, so the second hunk is required for the enum addition to compile.

`setRole` already has an `else` branch, so no `roleDescription` is set for the new value. That looks right to me, since Android has no tab bar concept to announce, but happy to add a string resource if you'd prefer one.

## Changelog:

[ANDROID] [FIXED] - Fix crash when `accessibilityRole="tabbar"` is used on Android

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

Test Plan:
Added a unit test to `ReactAccessibilityDelegateTest` asserting that `fromValue("tabbar")` resolves to `TABBAR` and maps to `android.view.View` rather than throwing.

Repro from the issue:

```jsx
<View accessibilityRole="tabbar">
  <Text>hello</Text>
</View>
```

Before: crashes on mount on Android with `Invalid accessibility role value: tabbar`.
After: renders as a plain view, matching iOS, where roles without a UIKit trait fall back rather than raising.

I have not run the Android suite locally, relying on CI for that.

Reviewed By: christophpurrer

Differential Revision: D115730694

Pulled By: Abbondanzo

fbshipit-source-id: ab0ac7987aa0fa0a4015a08514b8d83cfaa0323c
2026-08-12 19:43:17 -07:00
Peter Abbondanzo aa96fa64d1 Fix AccessibilityRole list conversion (#57926)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57926

Serialize `AccessibilityRole::List` as `list` and recognize `list` when parsing accessibility roles. Add exhaustive round-trip coverage for every named `AccessibilityRole`.

Changelog:
[General][Fixed] - Fix accessibility list role conversion in C++.

Reviewed By: christophpurrer

Differential Revision: D115746399

fbshipit-source-id: fdf4a74bbef7afe61ac18bf9adbc407cf29ac138
2026-08-12 17:22:53 -07:00
Sam Zhou aeee662b62 Deploy 0.327.0 to xplat (#57927)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57927

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

Reviewed By: gkz

Differential Revision: D115751796

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

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

## Changelog:

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

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

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

Reviewed By: christophpurrer

Differential Revision: D115586644

Pulled By: fabriziocucci

fbshipit-source-id: 6c0f1b435575c080444b72381f7ce56ae3f69a15
2026-08-12 12:37:41 -07:00
Jakub Kosmydel 7f18ad0f84 Ellipsize single-line TextInput placeholders (#57909)
Summary:
On Android, long `TextInput` placeholders are hard-clipped with no trailing ellipsis, while iOS truncates with `…`.

Fixes https://github.com/facebook/react-native/issues/29663 (same class of bug as https://github.com/facebook/react-native/pull/55272; uses a correct multiline bitmask check and clears ellipsize when multiline is enabled).

**Repro:** https://github.com/kosmydel/android-ellipsize-repro

| Before | After |
|--------|--------|
| <img width="400" alt="image" src="https://github.com/user-attachments/assets/583a8323-03ae-4075-a662-a4c92e8fec9e" /> |<img width="400" alt="image" src="https://github.com/user-attachments/assets/ece0f350-2349-4244-b7c8-56acd7d15e91" /> |

## Changelog

[Android] [Fixed] - Ellipsize long single-line TextInput placeholders to match iOS

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

Test Plan:
- Unit: `ReactTextInputPropertyTest` — placeholder sets `TruncateAt.END`; toggling `multiline` clears/restores ellipsize
- Manual: https://github.com/kosmydel/android-ellipsize-repro
  - Single-line constrained `TextInput` with a long placeholder → trailing `…`
  - Short placeholder unchanged
  - `multiline={true}` with a long placeholder → still wraps
  - Toggle `multiline` false → true → false → ellipsize restored

Reviewed By: christophpurrer

Differential Revision: D115724716

Pulled By: Abbondanzo

fbshipit-source-id: a267626a4b8d78d5e853729c46400b88a107d53a
2026-08-12 11:57:07 -07:00
Alex Hunt 7cdac2a15c Relocate manual .d.ts definitions under types_DEPRECATED/ (#57513)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57513

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

**Changes**

Rename the hand-written `types/` directory to `types_DEPRECATED/` and consolidate the co-located `.d.ts` declarations beneath it.

- This is a pure relocation with **no change** to the public type surface. The package `"exports"` map is updated so that every `types` condition resolves to the new location (`.` → `./types_DEPRECATED/index.d.ts`, `./Libraries/*` → `./types_DEPRECATED/Libraries/*.d.ts`) — consumers resolve the exact same types and runtime modules through the same import specifiers.
- Relative imports between the moved declarations, and the references from the moved `types/` files into `Libraries/`, were rewritten so the type graph continues to resolve.

**Downsides**

Risk of structural code drift if/when source modules in `Libraries/` move around.

**Counterpoint**: The aim here is to feature-lock the legacy JS API and remove deep `Libraries/` imports by projects.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D110602194

fbshipit-source-id: 14fbd9128821516e629f7e5b07cbfc7588fc335e
2026-08-12 10:16:06 -07:00
Nicola Corti 189bb445f6 Add Maestro Cloud CI for RNTester (#57919)
Summary:
This integrates our CI to work with Maestro Cloud.
The change is additive as the previous existing tests are untouched (also because the Debug Maestro tests require a running bundler which we can't have on Maestro Cloud).

## Changelog:

[INTERNAL] -

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

Test Plan: CI

Reviewed By: christophpurrer

Differential Revision: D115732295

Pulled By: cortinico

fbshipit-source-id: 20a5feb21ec130ba227655f415214f91548f2423
2026-08-12 10:06:37 -07:00
generatedunixname1430061942044674 f4803df9ec Daily arc lint --take KTFMT (#57918)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57918

Reviewed By: xavierd

Differential Revision: D115682996

fbshipit-source-id: c10d7e1b501225aa37c879573d47f00165472e08
2026-08-12 08:44:47 -07:00
Rohan Kulkarni 5906cfb060 Fix Text truncation at NULL character on iOS and Android (#24129) (#57906)
Summary:
Fixes https://github.com/react/react-native/issues/24129

**Problem:** `<Text>{'Hello \u0000 World'}</Text>` renders as "Hello" (truncated at \u0000). Does NOT reproduce when Debug JS Remotely (JSON preserves \u0000), but reproduces in production Hermes+Fabric on iOS and Android.

**Root cause:** JS String preserves \u0000 (length includes it), C++ std::string from JSI utf8() also preserves via size. Truncation happens at platform bridge where C-string NUL-terminated APIs are used:
- iOS: RCTAttributedTextUtils.mm:420 stringWithUTF8String:fragment.string.c_str() stops at embedded \0
- iOS: RCTConversions.h RCTNSStringFromString via stringWithCString: and reverse std::string{UTF8String}
- iOS: RCTTurboModule.mm convertJSIStringToNSString same
- Android: JavaTurboModule.cpp NewStringUTF(c_str()) expects NUL-terminated

**Fix (no new API):** Replace the C-string APIs with length-aware equivalents.

On iOS, `[[NSString alloc] initWithBytes:length:encoding:]` for std::string to NSString, and `dataUsingEncoding:` for the reverse, matching the existing correct pattern in FollyConvert.mm:31 and MapBufferBuilder.cpp.

On Android the conversion now goes through UTF-16 in both directions rather than UTF-8:
- outbound: `rt.utf16(...)` then `NewString(jchar*, len)`
- inbound: `GetStringLength()` + `GetStringChars()` then `jsi::String::createFromUtf16(...)`, released with `ReleaseStringChars`

That is worth calling out because it fixes a second latent bug. `NewStringUTF` expects *modified* UTF-8 (CESU-8), so it already mishandled 4-byte sequences such as emoji and other supplementary-plane characters. Going UTF-16 to UTF-16 avoids both problems.

All surfaces (Text, TextInput, accessibility, TurboModule params) are fixed at once because the shared converters are fixed.

## NOTE: nil becomes empty string at two call sites

RCTTurboModule.mm and RCTAttributedTextUtils.mm gain a `?: @""` fallback. Previously `stringWithUTF8String:` returned `nil` for invalid UTF-8 and callers received nil; they now receive `@""`. This matches the fallback `RCTNSStringFromString` already had, and `@""` is safer than nil for the ObjC call sites involved, but it is a behaviour change rather than a pure refactor.

## Changelog:
[GENERAL] [FIXED] - Fix Text truncation when string contains NULL character \u0000 (https://github.com/react/react-native/issues/24129)

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

Test Plan:
**Reproduction (RNTester):**
- Add screen Text > NullCharacter with <Text>{'Hello\u0000World'}</Text> and 'A\u0000B\u0000C'
- Before: "Hello" truncated
- After: "HelloWorld" full (invisible \0 zero-width but World visible, length preserved)

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

## Added on import: regression tests

Four cases added to the existing `React/Tests/Text/RCTAttributedTextUtilsTest.mm`, which is owned by `TextTestsApple`:

```
buck2 test fbsource//xplat/js/react-native-github:TextTestsApple
→ Pass 31. Fail 0.
```

Restoring the pre-fix `RCTConversions.h` and `RCTAttributedTextUtils.mm` and re-running fails all four and nothing else:

```
✗ RCTAttributedTextUtilsTest/testNSStringFromStringPreservesEmbeddedNull
✗ RCTAttributedTextUtilsTest/testStringFromNSStringPreservesEmbeddedNull
✗ RCTAttributedTextUtilsTest/testStringConversionRoundTripsEmbeddedNull
✗ RCTAttributedTextUtilsTest/testAttributedStringFromFragmentPreservesEmbeddedNull
Tests finished: Pass 27. Fail 4.
```

They cover `RCTNSStringFromString`, `RCTStringFromNSString`, a round trip through both, and the real AttributedString to NSAttributedString path. The changed function in RCTAttributedTextUtils.mm (`RCTNSAttributedStringFragmentFromFragment`) is static, so that last one goes through the public `RCTNSAttributedStringFromAttributedString`.

This replaces the original `node -p "'a\u0000b'.length"` check, which exercised JavaScript string length rather than any of the changed code.

The Android hunks are not covered by these tests. They are iOS-only test targets and there is no equivalent JNI-level unit test in tree, so the Android side rests on code review.

## On the reverse-direction allocation

`RCTStringFromNSString` now allocates an `NSData` where it previously used `UTF8String` (an interior pointer). That converter has 6 callers. The hot one is `RCTNSStringFromString` with 43 callers, and it does not add an allocation: `stringWithCString:` and `initWithBytes:` both allocate an NSString. Keeping the `NSData` form deliberately, because the cheaper alternative relies on `UTF8String`'s buffer containing embedded NULs, which is exactly the ambiguity this diff removes.

`arc lint -e extra` on the test file reports only pre-existing warnings plus a NULLSAFECLANG infrastructure failure.

Reviewed By: cipolleschi

Differential Revision: D115707536

Pulled By: fabriziocucci

fbshipit-source-id: 4cde8d4b584e0305fcfc3a4520f3690b411500cb
2026-08-12 08:22:32 -07:00
Dawid Małecki 93284f5c5a Define RN_BUILDING for React Native's own CocoaPods targets (#57858)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57858

`RN_BUILDING` marks React Native's own targets so the react/cxxstableapi guards stay inert for internal sources, which keep including fine-grained headers directly.

It is required whenever `RN_STRICT_API` reaches React Native's own compilation rather than only the consumer's:
- Project-wide enablement — a consumer applying the flag to every pod target (the CocoaPods post_install idiom) or through a global Buck config. Without RN_BUILDING, React Native's own translation units fail against their own guards.
- Private headers — `PrivateGuard.h` has no umbrella escape (#if defined(RN_STRICT_API) && !defined(RN_BUILDING)), so RN_BUILDING is the only way internal code can include them at all.

Mark every first-party pod as part of React Native's own build by defining
`RN_BUILDING` for it, through a new `mark_as_react_native_build` helper called last in
each spec block

This change is inert on its own: nothing behaves differently unless a consumer defines
`RN_STRICT_API`.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D115051089

fbshipit-source-id: f1178e2d0727827e5f40fc7b4a8f55b4d9b505cc
2026-08-12 08:21:39 -07:00
Dawid Małecki d3daf111e0 Let third-party pods resolve the C++ stable API guard headers (#57846)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57846

`install_modules_dependencies` is the helper every third-party New Architecture library calls from its own podspec, and `update_search_paths` covers the user project and the pod targets that don't go through it. Neither knew about `React-cxxstableapi`.

React Native's public C++ headers are starting to include the shared guard header `<react/cxxstableapi/UmbrellaGuard.h>`. The include is unconditional, so a third-party pod that includes any guarded React Native header has to be able to resolve it. Today it can't: in the default static-library mode `$(PODS_ROOT)/Headers/Public/React-cxxstableapi` is missing from the search path, and under `use_frameworks!` the `React_cxxstableapi.framework/Headers` entry is missing.

Declare the dependency and add the matching framework header search path in both places.

Changelog:
[iOS][Added] - Add a `React-cxxstableapi` dependency to third-party New Architecture pods so they can resolve React Native's C++ API guard headers

Reviewed By: cipolleschi

Differential Revision: D110052811

fbshipit-source-id: d72a8c0be4b667104a7e1b091130121f396396ba
2026-08-12 08:21:39 -07:00
Alan Hughes e71fc4e32f Fix RCTDevSettings init (#57409)
Summary:
https://github.com/react/react-native/issues/54258 made RCTPackagerConnection a per RCTDevSettings instance and creates it in init. The issue is that init isn't the only way these instances are built, anything constructed through the public initWithDataSource bypasses init entirely, so initWithDataSource never creates _packagerConnection and it stays nil. Those instances silently stop receiving packager commands like reload and devMenu, because the connection they would register handlers on and receive over does not exist.

This moves the creation into initWithDataSource, so every construction path gets a connection. -init still delegates to initWithDataSource:, so the default path is unchanged.

## Changelog:

[IOS] [FIXED] - Create the RCTDevSettings packager connection in initWithDataSource so instances built that way also receive packager commands

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

Test Plan:
- [[RCTDevSettings alloc] init].packagerConnection is non-nil (unchanged).
- [[RCTDevSettings alloc] initWithDataSource:dataSource]. packagerConnection is non-nil after this change (it was nil before).
- Verified in a host that subclasses RCTDevSettings via initWithDataSource (Expo Go's scoped dev settings), reload and devMenu from the CLI now reach the app over the packager connection. Before this change they were dropped because the subclass had a nil connection.

Reviewed By: vzaidman, cortinico

Differential Revision: D113387408

Pulled By: cipolleschi

fbshipit-source-id: bdf4b5b431c6870afd652e980022fb43c88bcb0c
2026-08-12 06:07:15 -07:00
Christoph Purrer 22cfb5caec Drop RCT_EXPORT_METHOD/RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD from RCTSampleTurboModule (#57903)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57903

`RCTSampleTurboModule` is a TurboModule: it conforms to
`NativeSampleTurboModuleSpec` and implements `getTurboModule:` returning the
codegen'd `NativeSampleTurboModuleSpecJSI`. For TurboModules, JS->ObjC dispatch
is driven by codegen (the generated spec supplies the `selector` and argument
kinds, invoked at runtime via `NSMethodSignature` / `NSInvocation`), not by the
macros' `__rct_export__` metadata. The macros are therefore dead weight here.

This converts all exported methods to plain ObjC method declarations —
both the async-void `RCT_EXPORT_METHOD` methods and, unlike the automated
codemod, the `RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD` ones, which are no longer
used. Conformance to the generated `protocol NativeSampleTurboModuleSpec`
keeps signature parity compiler-enforced.

Every implementation's declared argument types already matched the generated
protocol exactly, so no `RCTConvert` reconciliation or scalar boxing was
needed. Signature-only refactor with no change to the JS-facing API.

`RCT_EXPORT_MODULE()` is intentionally left in place — it is the module
registration, not a method export.

No C++ API snapshot regeneration is required: the `.api` snapshots describe the
codegen'd protocol header, which is unchanged, and the macros expanded to these
same selectors.

Changelog: [Internal]

Reviewed By: Abbondanzo

Differential Revision: D115635319

fbshipit-source-id: 45e5de9799bc6d7eb46ab5b7ecfaac2d8ed9915d
2026-08-11 17:31:59 -07:00
harsha-cpp 3e962d3800 guard shrink-factor division against floating-point near-zero (#57175)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57175

fixes https://github.com/facebook/yoga/issues/1665.

**problem:** when all flex children are frozen to their min-width in the first
pass, `totalFlexShrinkScaledFactors` is reduced to near-zero by floating-point
cancellation rather than exactly 0. the guard in `distributeFreeSpaceSecondPass`
uses exact equality (`== 0`), so it never fires, and the second pass divides
`remainingFreeSpace` by a value on the order of 1e-7, producing a childSize on
the order of 1e11 that overwhelms the min/max clamp.

**fix:** replace the exact-zero check with a relative epsilon guard
(`shrinkFactorMagnitude < 1e-6f`). when the magnitude is that small, all items
were already frozen in the first pass; the safe fallback (`childFlexBasis +
flexShrinkScaledFactor`) applies and the subsequent `boundAxisWithAutoMin` clamps
correctly to minWidth.

regression: `YGFlexShrinkBorderBug.flex_basis_0_border_minwidth_row` reproduces
the original crash — 4 children, `borderWidth` difference of 1e-6 across them,
all now compute to their correct minWidth.

## Changelog:
[Internal] -

X-link: https://github.com/facebook/yoga/pull/1974

Reviewed By: javache

Differential Revision: D108030908

Pulled By: cipolleschi

fbshipit-source-id: 3e8d4ef6773bc31703a54005bf610b2432f22d2d
2026-08-11 09:56:08 -07:00
Christoph Purrer b933d18177 Allow opting into RCT_REMOVE_LEGACY_*_INTEROP on iOS OSS (#57892)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57892

Changelog: [iOS][Added] - Allow consumers to opt into `RCT_REMOVE_LEGACY_MODULE_INTEROP` and `RCT_REMOVE_LEGACY_COMPONENT_INTEROP` from CocoaPods and SwiftPM. Both default to off and will become the default in a future release

OSS iOS consumers had no way to set `-DRCT_REMOVE_LEGACY_MODULE_INTEROP=1` and `-DRCT_REMOVE_LEGACY_COMPONENT_INTEROP=1`.
 This adds that, mirroring the existing
`RCT_REMOVE_LEGACY_ARCH` plumbing:

- `RCT_REMOVE_LEGACY_MODULE_INTEROP=1` / `RCT_REMOVE_LEGACY_COMPONENT_INTEROP=1` before
  `pod install` adds the define project-wide via
  `ReactNativePodsUtils.set_legacy_interop_removal_flags`.
- The same variables gate a matching `.define(...)` in `Package.swift`, so a
  build-from-source React Native compiles without the legacy interop layers too.

Both default to `0`. **They will default to `1` in a future release**, at which point
the env vars become opt-out.

The macros gate declarations in the public `RCTBridge.h` / `RCTBridgeModule.h`, so the
define is applied to the whole project rather than to React Native pods alone. When a
flag is enabled while using the prebuilt `React.xcframework`, `pod install` warns that
only the app-side pruning takes effect.

Reviewed By: cipolleschi

Differential Revision: D115490838

fbshipit-source-id: cac04eb0af7386a86fc1b06f280b39c52657543d
2026-08-11 09:55:41 -07:00
snowingfox 00a5aa9223 Fix RCTAppearance setColorScheme crashing CarPlay apps (non-UIWindowScene guard) (#57876)
Summary:
Fixes https://github.com/react/react-native/issues/57863

`RCTAppearance setColorScheme:` (also reached via `Appearance.setColorScheme()` and `setUserInterfaceStyle`) iterates `RCTSharedApplication().connectedScenes` and reads `scene.windows` on every scene. `connectedScenes` contains `UIScene` objects of any class, and a CarPlay `CPTemplateApplicationScene` is a `UIScene` that does not implement `windows`, so the message send raises `-[CPTemplateApplicationScene windows]: unrecognized selector` and the app aborts.

Fix: guard each scene with `isKindOfClass:[UIWindowScene class]` and skip non-`UIWindowScene` objects before touching `.windows`, mirroring the existing pattern already used in `RCTUtils.mm` (`if (![scene isKindOfClass:[UIWindowScene class]]) { continue; }`).

Note: `RCTDevMenu.mm` `showOnShake` has the same unguarded `for (UIWindowScene *scene ...)` loop and would crash identically in a CarPlay context; left untouched here to keep this fix minimal, but it should get the same guard.

## Changelog:

[IOS] [FIXED] - RCTAppearance.setColorScheme() no longer crashes CarPlay apps when connectedScenes contains a non-UIWindowScene

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

Test Plan:
No jest path exists for this code: it is Objective-C, iOS-only, and iOS cannot be built in the Linux environment this PR was developed in. Correctness is by code inspection.

Commands run (in the branch worktree):
- `git diff packages/react-native/React/CoreModules/RCTAppearance.mm` — confirms the only change is the 3-line guard:

```diff
  for (UIWindowScene *scene in RCTSharedApplication().connectedScenes) {
+   if (![scene isKindOfClass:[UIWindowScene class]]) {
+     continue;
+   }
    [windows addObjectsFromArray:scene.windows];
  }
```

- Code inspection of the edited region in full:

```objc
- (void)setColorScheme:(NSString *)style
{
  UIUserInterfaceStyle userInterfaceStyle = [RCTConvert UIUserInterfaceStyle:style];
  NSMutableArray<UIWindow *> *windows = [NSMutableArray new];
  for (UIWindowScene *scene in RCTSharedApplication().connectedScenes) {
    if (![scene isKindOfClass:[UIWindowScene class]]) {
      continue;
    }
    [windows addObjectsFromArray:scene.windows];
  }

  for (UIWindow *window in windows) {
    window.overrideUserInterfaceStyle = userInterfaceStyle;
  }
}
```

The guard makes `setColorScheme` tolerate any non-`UIWindowScene` object in `connectedScenes` by skipping it before the `.windows` message send. `isKindOfClass:` is safe to send to any `UIScene` (all are `NSObject`-derived), so the previously-crashing path is unreachable for CarPlay scenes.

This matches the reporter's production `patch-package` fix that has been field-tested on-device since 2026-08-02.

Reviewed By: cipolleschi

Differential Revision: D115451211

Pulled By: christophpurrer

fbshipit-source-id: ce372259d908355fff077b17df828308f75bffcf
2026-08-11 09:11:34 -07:00
Zeya Peng c0a4e1444a Consolidate v0.87.0-RC changelog entries into a single v0.87.0 section (#57901)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57901

The 0.87 release notes were split across five release-candidate sections
(rc.0 through rc.4). Merge them into a single v0.87.0 section without changing
any entry text:

- Combine all five RC sections under a single `v0.87.0` heading
- Organize entries under the standard Breaking / Added / Changed / Deprecated /
  Removed / Fixed / Security categories, each with general / Android specific /
  iOS specific subsections
- Sort entries within every subsection by their bold prefix
- Triage the changelog generator's `Unknown` and `Android Unknown` buckets into
  real categories rather than dropping them: the `EventEmitter.cpp` data-race
  fix moves to `Fixed`, and the remaining automated Flow, Kotlin, i18n, and
  build-tooling entries move to `Changed`
- Drop empty subsection headings
- No entries were added, removed, or reworded

Changelog: [Internal]

Reviewed By: fabriziocucci

Differential Revision: D115575927

fbshipit-source-id: 889ca0317fb7c31f2b657ae78afb6b9ae1825b52
2026-08-11 08:32:51 -07:00
Alex Hunt 93f1e6af74 Drop outdated links to wiki (#57898)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57898

Changelog: [Internal]

___

Differential Revision: D115564599

fbshipit-source-id: 4714995277556fc60550780e7a911e60eeef2f0d
2026-08-11 04:46:28 -07:00
artus9033 7bfe32fd33 Add SceneDelegate support (#57700)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57700

Add SceneDelegate lifecycle support to React Native iOS while retaining the AppDelegate path for backwards compatibility.

Update linking, window resolution, bootstrap APIs, RNTester, HelloWorld, and generated API snapshots for scene-based applications.

Changelog:
[iOS][Added] - Add SceneDelegate lifecycle support

Test Plan:
- `buck2 build --flagfile fbsource//fbobjc/mode/buck2/linux --config fbobjc.react_native_debug=development --flagfile fbsource//fbobjc/mode/iphonesimulator-arm64 --flagfile fbsource//fbobjc/mode/jest-coverage --config xplat.available_platforms=CXX,APPLE --config cxx.default_platform=iphonesimulator-arm64 --config user.sandcastle_build_mode=profile --config user.platform_flavor=iphonesimulator-arm64 //xplat/js/react-native-github/packages/rn-tester:RNTesterIOS`
- `xcodebuild -quiet -workspace RNTesterPods.xcworkspace -scheme RNTester -configuration Debug -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build`
- `arc lint`
- Evaluate RNTester with the `RNTester` SceneDelegate scheme.
- Evaluate RNTester with the `RNTester (AppDelegate)` legacy scheme.
- Verify HelloWorld bootstrap and deep linking.

Reviewed By: cortinico, javache

Differential Revision: D113758228

Pulled By: cipolleschi

fbshipit-source-id: 31174c03a0936ca397fc1d061650fc0f582bdda7
2026-08-11 03:59:23 -07:00