Christian Falch
90d · built 2026-07-24
90-day totals
- Commits
- 13
- Grow
- 13.8
- Maintenance
- 0.9
- Fixes
- 1.3
- Total ETV
- 15.9
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+900.0 %
vs 1 prior
↑+86.8 pp
recent vs prior
↑+7.6 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
| Repo | Commits | ETV |
|---|---|---|
| react-native | 12 | 15.9 |
Most impactful commits
Top 20 by ETV in the 90-day window.
- 11.4ETVfeat(iOS) swiftpm support in iOS (#57332) Summary: ⚠️ This is a stacked PR — review/merge the base PRs first Builds on, and should land after (bottom-up): 1. https://github.com/react/react-native/issues/57285 — Remove the Clang VFS overlay / modularize React headers (base of the stack). <React/…> via the framework module map; lowercase namespaces (react/, yoga/, jsi/, …) via the ReactNativeHeaders module map. 2. https://github.com/react/react-native/issues/57305 — Prebuilt artifact resources + ReactNativeHeaders.xcframework. Ships the prebuilt core artifacts (incl. ReactNativeHeaders in the tarball + embedded React.framework resources) and the CocoaPods React-Core-prebuilt facades. 3. https://github.com/react/react-native/issues/57440 — Self-serving prebuilt ReactNativeDependencies + dependency-only facades. The deps pod becomes the single header authority for the third-party namespaces (RCT-Folly/glog/boost/…); community `s.dependency "RCT-Folly"` resolves to local facades instead of trunk source pods. 4. https://github.com/react/react-native/issues/57442 — ReactNativeDependenciesHeaders sidecar + pure-RN ReactNativeHeaders (immediate base). The deps prebuild emits a headers-only LIBRARY-type sidecar (the binary deps xcframework is framework-type — invisible to SwiftPM binaryTargets), ReactNativeHeaders drops the third-party namespaces, and both headers artifacts publish standalone to Maven. The whole stack is rebased onto current main (2026-07-06). This PR consumes the final **five-artifact set**: React, ReactNativeHeaders (pure-RN), ReactNativeDependencies, ReactNativeDependenciesHeaders, hermes-engine. Adds npx react-native spm and the package-generation tooling that turns an app into a SwiftPM-integrated RN app using the base stack's prebuilt XCFrameworks. CocoaPods stays supported — additive, opt-in, no Ruby toolchain. Integration is injected into the existing .xcodeproj in place (nothing generated/renamed/replaced), recorded in .spm-injected.json so it reverses exactly. ### What this PR adds - The spm CLI (add/update/deinit/scaffold + hidden sync/codegen/download), zero-arg auto-resolution, --deintegrate for CocoaPods→SwiftPM. - SwiftPM package generation (scripts/spm/): autolinking→Package.swift, Codegen→React-GeneratedCode, core XCFramework binary targets, artifact download/cache, surgical pbxproj inject/remove. - ReactNativeDependenciesHeaders wired as the 5th binaryTarget: the headers-only companions (ReactNativeHeaders from the core tarball, the deps sidecar from the deps tarball) are staged automatically out of their parent tarballs — no --headers-tarball priming; REQUIRED_ARTIFACTS covers all five. - Community-library scaffolding from podspecs (incl. root-level-source podspecs via generated include/<SwiftName>/ shims, sibling wiring for transitive spm.dependencies, self-ingestion guards). - In-place Xcode integration (XCLocalSwiftPackageReference + Sync build phase + scheme pre-action + auto-sync; ${PODS_ROOT}-anchored REACT_NATIVE_PATH replaced on --deintegrate with exact deinit rollback). - rn-tester + helloworld SwiftPM consumption + test library; npm-packaging hygiene; a small RNCoreFacades.podspec_dir fix. ## Documentation - **Tool docs** (usage, quick start, architecture): [`scripts/spm/__doc__/spm-scripts.md`](https://github.com/react/react-native/blob/chrfalch/swift-package-manager/packages/react-native/scripts/spm/__doc__/spm-scripts.md) - **Header-paths contract** (how the five artifacts serve headers): [`scripts/spm/__doc__/spm-header-paths-contract.md`](https://github.com/react/react-native/blob/chrfalch/swift-package-manager/packages/react-native/scripts/spm/__doc__/spm-header-paths-contract.md) - **RFC** (updated): [react-native-community/discussions-and-proposals#994](https://github.com/react-native-community/discussions-and-proposals/pull/994) ## Changelog: [IOS] [ADDED] - `npx react-native spm` command + SwiftPM package-generation tooling (opt-in; CocoaPods stays supported) Pull Request resolved: https://github.com/react/react-native/pull/57332 Test Plan: 350 scripts/spm unit tests (incl. byte-identical add→deinit round-trip); manual E2E against the five-artifact set: fresh app via `cli init`→`spm add --deintegrate`→build (artifact resources verified in the app), rn-tester in-place migration (RNTesterPods.xcodeproj, test libraries + spmModules), helloworld in-place migration — all BUILD SUCCEEDED. Verified `npx react-native spm <cmd>` from the command line in each journey. ## Scope & limitations iOS, prebuilt-only (no build-from-source yet); full spm.xcframework/spm.source library metadata not yet (app-local spm.modules + scaffolding are); Expo not yet. ## Follow-ups Remote-mode ReactNative Package.swift must vend the ReactNativeDependenciesHeaders product (spm-distribution repo); library self-containment for repo-portable manifests; build-from-source. Reviewed By: mdvacca Differential Revision: D111449548 Pulled By: cipolleschi fbshipit-source-id: 87a873bf5c8be2d60f7893611e16924bfa730a46github.com-facebook-react-native · 47fad096 · 2026-07-15
- 1.9ETVrefactor(ios): remove clang VFS overlay, resolve headers via new ReactNativeHeaders framework (#57285) Summary: The prebuilt `React.xcframework` previously relied on a Clang VFS overlay (`React-VFS.yaml`) to make headers importable, because the headers were laid out in CocoaPods-style namespaced folders rather than standard framework conventions. The overlay had to be generated at build time, re-resolved at pod-install time per slice, and injected as `-ivfsoverlay` flags into every Obj-C, C++, and Swift compile (including aggregate and third-party pod targets). This is fragile, hard to reason about, and incompatible with SwiftPM consumption. This PR removes the VFS overlay entirely and resolves headers through standard framework/header-search-path mechanics instead. **Headers are now emitted into the artifact according to an explicit, executable spec:** - **`React.xcframework`** — each slice's `React.framework` carries every `<React/...>` header plus a framework module map, so `#import <React/...>` and `import React` resolve through `FRAMEWORK_SEARCH_PATHS` automatically. - **`ReactNativeHeaders.xcframework`** (new, headers-only) — carries every other namespace (`<react/...>`, `<yoga/...>`, `folly`, `glog`, …), shipped alongside in the prebuilt tarball and exposed via a single header search path. - This makes `ReactNativeDependencies` binary-only. No clang VFS overlay, no per-target `-ivfsoverlay` flags. The layout is driven by a single source of truth (`headers-spec.js`, rules R1–R11) that both the prebuild compose step and downstream SwiftPM tooling derive from, so the shipped header set cannot drift from the spec. Source headers are byte-identical to the repo — the only consumer-facing change needed is bare-form angle includes (`#import <RCTAppDelegate.h>` → `#import <React/RCTAppDelegate.h>`). **Consumer surfaces the flattened layout initially dropped are restored** (validated against Expo and community Fabric modules): - Private headers (`RCTBridge+Private.h` + the Fabric `RCTComponentView*` family) are exposed in the `React` module map — modular where safe, `textual` where they reach C++ — so frameworks like Expo compile unchanged, incl. Swift access to `RCTBridge.moduleRegistry`. - `React_RCTAppDelegate-umbrella.h` is re-emitted (derived from the live header set) for consumers probing it via `__has_include`. - Sources shipping under multiple include spellings (`React/X.h` + legacy `CoreModules/…`, `RCTImage/…`, bare aliases — 116 today) keep content at ONE module-owned spelling; other spellings become generated redirect shims, so `-fmodules` consumers cannot hit duplicate declarations. - The `React-RCTFabric` facade re-vends `RCTFabricComponentsPlugins.h` at `header_dir "React"`, keeping community Fabric modules' quoted `#import "RCTFabricComponentsPlugins.h"` working as with source pods. **The layout is verified at generator time** (`headers-verify.js`, runs in the prebuild compose CI job): unresolvable includes ratchet against a committed baseline, composed module maps/umbrellas must byte-match the spec render, and consumer-shaped compile smokes must pass (the `React` module, every namespace module, an Expo-shaped ObjC++ fixture, and a Swift `moduleRegistry` fixture). Fail-closed guards cover header collisions, allowlist drift, and missing OR undeclared third-party deps namespaces (the latter surfaced `SocketRocket`, which is deliberately NOT relocated — the real pod vends it, and textual copies collide under `use_frameworks`; the gate asserts its absence). **Key changes** - **New**: `headers-spec.js` (the executable layout contract, R1–R11), `headers-compose.js` (emitter for both xcframeworks), `headers-inventory.js` (podspec-driven header classifier feeding the spec + a diagnostic manifest), `headers-verify.js` (generator-time gate + CI step), `__docs__/headers-rules.md` (rules + rationale). - **Removed**: `vfs.js`, VFS types in `types.js`, and the VFS processing/flag-injection paths in `rncore.rb` and `xcframework.js`. - **Updated**: `React-Core-prebuilt.podspec` (vends both xcframeworks, flattens `ReactNativeHeaders` headers into `Headers/` via `prepare_command`, fails closed on incomplete tarballs), `rncore.rb` / `react_native_pods.rb` (header search path instead of overlay flags), `prebuild-ios-core.yml` (core tarball ships both xcframeworks; compose job verifies the composed headers), README (VFS docs replaced with the new model). - Added facades to the Podspecs that shouldn't be in use when running using precompiled frameworks to satisfy dependencies as empty pod-specs (with the single `RCTFabricComponentsPlugins.h` re-vend exception noted above). ## Changelog: [IOS] [CHANGED] - Remove the Clang VFS overlay from prebuilt React Native Core; resolve headers via React.xcframework + a new headers-only ReactNativeHeaders.xcframework Pull Request resolved: https://github.com/react/react-native/pull/57285 Test Plan: - [x] rn-tester builds against the prebuilt `React-Core-prebuilt` pod (Debug + Release) with no `-ivfsoverlay` flags present in the generated xcconfigs. - [x] rn-tester builds against React native source code (without any prebuilt artifacts) - [x] `#import <React/...>`, `import React;`, and the relocated namespaces (`<react/...>`, `<yoga/...>`, `folly`/`glog`) all resolve. - [x] Prebuilt tarball contains both `React.xcframework` and `ReactNativeHeaders.xcframework`; pod install flattens headers into `React-Core-prebuilt/Headers`. - [x] Switch RN-tester between Debug/Release and verify that both `React.xcframework` and `ReactNativeHeaders.xcframework` are changed between debug and release correctly. - [x] `headers-verify.js` gate green on Debug and Release composes (`-Werror=non-modular-include-in-framework-module` never trips in consumer builds). - [x] `private/helloworld` builds against the prebuilt core (CocoaPods path). - [x] Expo SDK compiles against the prebuilt artifacts (private headers, `React_RCTAppDelegate` umbrella probe, Fabric quoted imports). Reviewed By: fabriziocucci Differential Revision: D111448598 Pulled By: cipolleschi fbshipit-source-id: 72bc2f37765ad425722161a038e410ba976858a5github.com-facebook-react-native · 376bd0e4 · 2026-07-15
- 0.7ETVfeat(iOS): ReactNativeDependenciesHeaders sidecar + pure-RN ReactNativeHeaders, published to Maven (#57442) Summary: Step 2 of the prebuilt-deps roadmap: ship the deps headers as a **SwiftPM-ready, self-contained artifact** and make every header namespace have exactly **one physical home**. 1. **New artifact: `ReactNativeDependenciesHeaders.xcframework`** — the binary `ReactNativeDependencies.xcframework` is framework-type, so its root `Headers/` is invisible to SwiftPM binaryTargets (`HeadersPath` is rejected on framework entries; verified empirically). The deps prebuild now emits a headers-only library-type sidecar (stub archives + per-slice `Headers/` + `HeadersPath` — the exact `ReactNativeHeaders` recipe, factored into a shared `headers-xcframework.js` emitter) carrying all seven deps namespaces incl. SocketRocket, with slice parity derived from the binary artifact's Info.plist. Ships inside the deps tarball *and* standalone. 2. **`ReactNativeHeaders` goes pure-RN** — the R2 relocation of deps namespaces (and the `DEPS_NAMESPACES_NOT_RELOCATED` SocketRocket exclusion list) is deleted. Relocated copies are what enabled the SocketRocket dual-copy regression (duplicate `interface` / poisoned module graph under `use_frameworks!`); that bug class is now structurally impossible. Headers gate flipped: deps namespaces must be **absent** from RNH; the sidecar emitter enforces set-equality with `DEPS_NAMESPACES` fail-closed in both directions. On the CocoaPods side, a new `ReactNativeDependenciesUtils.configure_aggregate_xcconfig` injects the deps pod's `Headers/` globally (aggregate + every pod target), mirroring the rncore injection — this replaces the folly/glog resolution pods previously got via the flattened `React-Core-prebuilt/Headers`. 3. **CI: prebuilt + dynamic-frameworks lane** — the regression's exact config had no coverage (the `test-ios-rntester` action hard-coupled `use-frameworks:true` to source builds). New `use-prebuilds` input; `test_ios_rntester`'s dynamic cells now consume the workflow-built prebuilt artifacts. 4. **Maven publishing** — `ReactNativeHeaders` and `ReactNativeDependenciesHeaders` publish standalone on `react-native-artifacts` (classifiers `reactnative-headers-*`, `reactnative-dependencies-headers-*`); `verifyArtifactsAreOnMaven` now HEAD-checks every classifier tarball instead of only the POM. Stacked on https://github.com/react/react-native/issues/57440. The SwiftPM preview (https://github.com/react/react-native/issues/57332) rebases on top and wires the sidecar as its 5th binaryTarget. ## Changelog: [IOS] [CHANGED] - Prebuilt artifacts: ReactNativeHeaders is pure-RN; third-party deps headers ship in the new ReactNativeDependenciesHeaders.xcframework sidecar (and the ReactNativeDependencies pod), published standalone to Maven Pull Request resolved: https://github.com/react/react-native/pull/57442 Test Plan: - Headers gate: include-health, structural (deps absent from RNH, byte-matched module maps), and compile smokes (React module + 14 namespace modules + Expo-shape ObjC++/Swift fixtures vs the deps include path) — ALL PASSED - jest: 33/33 (`scripts/ios-prebuild/__tests__`, incl. new sidecar set-equality tests) - ESLint (`--max-warnings 0`), Prettier, Flow (`yarn flow-check`): clean - E2E (locally built artifacts): rn-tester prebuilt static ✅, prebuilt `USE_FRAMEWORKS=dynamic` ✅ (the regression config — verified `React-Core-prebuilt/Headers` contains no deps namespaces and the deps pod serves all seven), helloworld static ✅, source-core + prebuilt-deps ✅ (React compiled from source resolves folly via the deps pod), source-mode control with unchanged dependency graph ✅ - Sidecar inspected: per-slice `HeadersPath`, 7 namespaces, slice parity with the binary - Publication validated end-to-end with `publishReleasePublicationToMavenLocal`: all 12 files + POM land with the expected classifier names 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D111449462 Pulled By: cipolleschi fbshipit-source-id: e1217d14c0588d00a207622d346c9e6f4705a95dgithub.com-facebook-react-native · 6aa147f6 · 2026-07-15
- 0.6ETVrefactor(iOS): include resources like bundles into the precompiled XCFrameworks (#57305) Summary: **Depends on https://github.com/react/react-native/issues/57285** In source builds, `React-Core` ships non-header resources — its privacy manifest (`PrivacyInfo.xcprivacy`) and its localized strings (RCTI18nStrings) — via the podspec's resource_bundles. In the prebuilt path those source pods aren't installed (CocoaPods facades) or aren't present at all (SwiftPM), so these resources were silently dropped: prebuilt/SwiftPM apps shipped no React Native privacy manifest, and localized strings were unavailable. This embeds them in React.framework at prebuild time so they ship uniformly across CocoaPods-prebuilt and SwiftPM, with source builds unchanged: - **Privacy manifest** — the PrivacyInfo.xcprivacy of the pods baked into React.framework are merged into one manifest at the framework root. React.framework is a dynamic framework, so Xcode's privacy-report aggregation picks it up automatically (no runtime involvement). - **RCTI18nStrings** — rebuilt as RCTI18nStrings.bundle inside React.framework. RCTLocalizedString.mm now resolves the bundle from its own framework first (bundleForClass:), falling back to the app's main bundle for static source builds. It also fixes a latent bug in `React-Core.podspec`: a later resource_bundles = was overwriting the earlier resource_bundle =, so source builds had stopped shipping RCTI18nStrings. Both bundles are now declared together. With the artifact owning these resources, the prebuilt RNCore facade no longer carries them. ## Changelog: [IOS][FIXED] - Ship React-Core's privacy manifest and localized strings (RCTI18nStrings) inside the prebuilt React.xcframework, so CocoaPods-prebuilt and SwiftPM apps include them Pull Request resolved: https://github.com/react/react-native/pull/57305 Test Plan: - ✅ yarn jest packages/react-native/scripts/ios-prebuild — unit + integration tests for the merge/discovery/bundle-build logic (red/green). - ✅ Built React.xcframework from this branch and confirmed each slice's React.framework carries the merged PrivacyInfo.xcprivacy and RCTI18nStrings.bundle (37 locales). - ✅ Cold-built rn-tester in prebuilt mode and verified the app bundle contains Frameworks/React.framework/{PrivacyInfo.xcprivacy, RCTI18nStrings.bundle}. - ✅ Confirmed React-Core.podspec now reports both resource bundles (RCTI18nStrings, React-Core_privacy) for source builds. Reviewed By: fabriziocucci Differential Revision: D111448862 Pulled By: cipolleschi fbshipit-source-id: a95360f51cc1131510ef03f7e48c689575d1c22dgithub.com-facebook-react-native · 77b75122 · 2026-07-15
- 0.4ETVfeat(iOS): serve third-party deps from the prebuilt ReactNativeDependencies pod via dependency-only facades (#57440) Summary: Step 1 of making the prebuilt `ReactNativeDependencies` pod the **single header authority** for the third-party C/C++ deps (RCT-Folly, glog, boost, DoubleConversion, fmt, fast_float, SocketRocket) in prebuilt-deps mode. Today the deps **binary** replaces the source pods' code, but the pod still `s.dependency`'s the real source pods and borrows their headers via `$(PODS_ROOT)/<pod>` search paths. That split header authority is the dual-copy bug class behind the 2026-07-03 SocketRocket regression (`duplicate interface` under `use_frameworks!` — SocketRocket's ObjC headers have no include guards). Three commits: 1. **fix(cocoapods): harden prebuilt-deps header search paths and artifact handling** — `rndependencies.rb`'s `||= [] << path` only added the deps header search path when `HEADER_SEARCH_PATHS` was unset (silently dropped otherwise); normalize and always append, and point at the pod-local flattened `Headers/`. `ReactNativeDependencies.podspec` `prepare_command` now fails closed (`exit 1`) instead of silently producing a no-link pod. `reactNativeDependencies.js` no longer deletes + re-downloads a locally staged artifact that lacks a version marker. 2. **feat(cocoapods): dependency-only facades for third-party pods in prebuilt-deps mode** — in prebuilt-deps mode the real source pods are not declared, so a community podspec's hardcoded `s.dependency "RCT-Folly"` would resolve from trunk and compile from source next to the prebuilt binary. `RNDepsFacades` generates dependency-only local facade podspecs (no sources, no headers, a single dependency on `ReactNativeDependencies`); versions/subspecs are derived from the real podspecs in `third-party-podspecs/` (SocketRocket synthesized fail-closed from `socket_rocket_config`). Full contract documented in `scripts/cocoapods/__docs__/prebuilt-deps.md`. 3. **feat(ios-prebuild): SocketRocket privacy manifest + Xcode 26 header layout** — embed an RN-authored, accurate-empty `PrivacyInfo.xcprivacy` for SocketRocket (upstream ships none), and stage flat public headers into `include/` so Xcode 26's SwiftPM accepts the header layout. Stacked on https://github.com/react/react-native/issues/57305 (base: `chrfalch/prebuilt-resources`); the SwiftPM preview (https://github.com/react/react-native/issues/57332) rebases on top of this. Follow-up (separate PR): headers-only `ReactNativeDependenciesHeaders.xcframework` sidecar so SPM auto-serves the deps namespaces and `ReactNativeHeaders` goes pure-RN. ## Changelog: [IOS][CHANGED] - Prebuilt-deps mode: serve third-party headers from the ReactNativeDependencies pod itself and resolve community `s.dependency` on RCT-Folly/glog/boost/etc. via dependency-only facade pods Pull Request resolved: https://github.com/react/react-native/pull/57440 Test Plan: E2E matrix (2026-07-06, locally built deps artifact via `prepare-ios-prebuilds.js`): - rn-tester, prebuilt core + prebuilt deps, static linkage — builds - rn-tester, prebuilt core + prebuilt deps, `USE_FRAMEWORKS=dynamic` — builds (the SocketRocket-regression config) - helloworld (private), prebuilt core + prebuilt deps, static — builds - source-mode control: no facades generated, `Podfile.lock` identical to baseline 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D111449257 Pulled By: cipolleschi fbshipit-source-id: ace5716868d126a08721200efd640e903b191658github.com-facebook-react-native · a8156acf · 2026-07-15
- 0.2ETVfix(iOS): stamp the React Native version in the prebuild compose job (#57603) Summary: `prebuild-ios-core.yml` builds the prebuilt iOS core in two jobs: **`build-rn-slice`** compiles the React binary per platform slice, and **`compose-xcframework`** runs afterwards in its **own fresh checkout**, downloads the slice artifacts, and composes the shipped `React.xcframework` + `ReactNativeHeaders.xcframework` — re-deriving the shipped *headers* from that checkout. The "Set React Native version" step runs only in `build-rn-slice`. So the compiled **binary is stamped**, but the composed **headers are not**: the artifact ships `ReactNativeVersion.h` with the `1000.0.0` dev sentinel, internally inconsistent with its own binary (and with the npm package, which is stamped in its own publish job). This was latent for as long as the compose job has existed — it only started breaking consumers now because the header-facades / VFS-overlay-removal work changed *which file libraries actually read*. Previously header resolution (the VFS overlay, and the `Pods/Headers/Public` symlinks of the source pods) redirected reads to the **stamped npm copy**, so the sentinel bytes in the tarball were never consumed. With real materialized headers, the prebuilt copy now wins the search path, and any library gating on `REACT_NATIVE_VERSION_MAJOR/MINOR` compiles the wrong branch. That breaks `[ios] react-native-unistyles` in nightly-tests: its `#if REACT_NATIVE_VERSION_MINOR >= 81` sees `MINOR 0` and picks a removed pre-0.81 path (`shadowNodeFromValue`). **Fix — built-headers overlay (no re-stamp/revert).** The `build-rn-slice` job already stamps its checkout before building and uploads `.build/headers`, and the compose job already downloads it — it was just unused. `stageEntries` now takes an overlay dir and, **for `ReactNativeVersion.h` only**, prefers the built copy (stamped in the slice job) over the source sentinel. Header **layout** is still spec-derived from source (podspec inventory, collision detection, classification), and every **other** header still copies from source — so a stale build tree can never ship wrong header content, only the one build-generated version header is overlaid. No stamping of the compose checkout, no `git revert`, no cache-key desync. The compose cache key is bumped so pre-fix (unstamped) composed artifacts cached under the old key are not served. **Guard.** `headers-verify.js` gains `--require-stamped-version` (passed when a `version-type` is set) that hard-fails the compose verification if any composed `ReactNativeVersion.h` still contains the sentinel — turning any future regression into a red prebuild instead of silently broken community libraries. ## Changelog: [IOS] [FIXED] - Ship a version-stamped ReactNativeVersion.h in the prebuilt iOS core artifacts instead of the 1000.0.0 dev sentinel Pull Request resolved: https://github.com/react/react-native/pull/57603 Test Plan: - Local compose with a stamped `ReactNativeVersion.h` seeded into `.build/headers` and the source tree left at the `1000` sentinel: all composed `ReactNativeVersion.h` copies come out stamped (overlay won), while a deliberately **stale** `.build/headers/…/TraceRecordingState.h` is correctly ignored — the composed `TraceRecordingState.h`/`HostTracingProfile.h` come from source, and other headers + module maps/umbrellas are unaffected (structural gate passes). - Guard: composed layout with a sentinel header → `verifyVersionStamp` throws listing the offending files; stamped → `version stamp OK (N copies checked)`; no effect without the flag. - Verified against a fresh RN-nightly app + `react-native-unistyles@3.3.0` on Xcode 26.3 (prebuilt mode) and in the Expo prebuilt harness (26.3 + 26.6): stock prebuilt headers reproduce the `shadowNodeFromValue` error; the stamped prebuilt header resolves it. - End-to-end proof is the next nightly run: the composed tarball must carry a stamped header. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: javache Differential Revision: D113005220 Pulled By: cipolleschi fbshipit-source-id: 5fbba8bb4e84fd1458a2f4a0baa623cf613b6e3bgithub.com-facebook-react-native · 95df5003 · 2026-07-21
- 0.2ETVfix(iOS): dedupe SPM package module maps by building spm_dependency pods into the shared products dir (#57602) Summary: The nightly-tests job `[ios] react-native-enriched-markdown` fails on Xcode 26.3 (the CI runner version) with `error: redefinition of module 'RaTeXFFI'`. The library declares an `spm_dependency` on a Swift package (RaTeX) containing a C-family target, and Xcode emits the package's generated `include/module.modulemap` **twice**: into the shared products dir and into the pod's own `CONFIGURATION_BUILD_DIR`. Both copies are unavoidably visible to the pod's compile: - the package's `.swiftmodule` **serializes** the products-root include path in its recorded clang args and replays it on import, and - Xcode's built-in `-I$(BUILT_PRODUCTS_DIR)/include` exposes the per-pod copy. Clang parses two files defining the same module and hard-errors on Xcode 26.3 (26.5+ tolerates the duplicate). Because the root path is serialized inside the swiftmodule, no search-path change can hide it — and the `SWIFT_ENABLE_EXPLICIT_MODULES=NO` opt-out (https://github.com/react/react-native/issues/57589, and the equivalent podspec-side opt-out already shipped in react-native-enriched-markdown) is confirmed insufficient: the failing nightly contains it. **Fix**: build static-library `spm_dependency` pod targets straight into the shared products dir (`CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}`), so both module-map references resolve to the *same file* (clang dedupes same-path module maps). This also places the package swiftmodule on the pod's default search path, which replaces the old `SWIFT_INCLUDE_PATHS` "Swift package not found" workaround for these targets. The aggregate xcconfigs' `-fmodule-map-file` references are rewritten to the flattened location by mutating the shared in-memory `Config` objects (later `post_install` steps re-save those same objects, so a plain file edit would be clobbered). `USE_FRAMEWORKS=dynamic` keeps the previous behavior unchanged. Supersedes https://github.com/react/react-native/issues/57589. ## Changelog: [IOS] [FIXED] - Fix "redefinition of module" build failure on Xcode 26.3 for pods using spm_dependency with prebuilt React Native core Pull Request resolved: https://github.com/react/react-native/pull/57602 Test Plan: All on a fresh RN-nightly app with `react-native-enriched-markdown` under `RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1` (the nightly-tests configuration): - Red baseline reproduced CI exactly on Xcode 26.3 (13× `redefinition of module 'RaTeXFFI'`). - With this change (plain `pod install`, clean DerivedData): **BUILD SUCCEEDED on Xcode 26.3, 26.6, and 27.0 beta 3**, Debug and Release, zero module errors. - `USE_FRAMEWORKS=dynamic`: unchanged behavior (legacy code path taken, verified via pod install log). - Regression net without any `spm_dependency` pod (change must be inert): helloworld × {prebuilt, source} × {static, dynamic} × Debug — 4/4 build + install + launch PASS. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: cortinico Differential Revision: D112796678 Pulled By: cipolleschi fbshipit-source-id: f6e988fae8954b3b245180e6a66d600a6406a75egithub.com-facebook-react-native · 4a662070 · 2026-07-20
- 0.2ETVfix(iOS): exclude C++-guarded foreign-namespace headers from React umbrella (#57575) Summary: The first nightly containing the prebuilt/SwiftPM stack (`0.88.0-nightly-20260716`) broke the `react-native-unistyles` job in [react-native-community/nightly-tests](https://github.com/react-native-community/nightly-tests/actions/runs/29476835418/job/87551592185) with: ``` Pods/Headers/Public/React-Core-prebuilt/react/timing/primitives.h:28:7: error: redefinition of 'HighResDuration' note: additional include site in header from module 'ReactNativeHeaders_react' note: additional include site in header from module 'React.RCTFrameTimingsObserver' → could not build module 'React' ``` **Root cause:** `RCTFrameTimingsObserver.h` includes `<jsinspector-modern/tracing/FrameTimingSequence.h>` under `#ifdef __cplusplus`, transitively reaching `react/timing/primitives.h`, which is owned by the `ReactNativeHeaders_react` module. The headers inventory's reachability fixpoint only follows *unguarded* include edges (modeling a pure-ObjC consumer), so it couldn't see this edge and classified the header as umbrella-safe. Swift pods with C++ interop (unistyles, Nitro-based libs) build the `React` clang module as ObjC++, opening the guard — one header owned by two modules in a single compilation → C++ redefinition errors. Pure-ObjC consumers never open the guard, which is why only C++-interop libraries failed. **Fix:** a curated `UMBRELLA_CXX_GUARDED_EXCLUSIONS` set checked in `isUmbrellaSafe`, mirroring the existing `PRIVATE_REACT_HEADERS` pattern, with fail-closed validation (`validateUmbrellaExclusions`, wired into `planFromInventory`) so a renamed/deleted entry surfaces immediately. The header still ships in `React.framework/Headers` and stays importable via `#import <React/RCTFrameTimingsObserver.h>` (its only consumer today is `RCTHost.mm`); it is only removed from the modular umbrella surface. If a modular consumer ever needs it, it can be promoted to a `PRIVATE_REACT_HEADERS.textual`-style entry instead. ## Changelog: [IOS] [FIXED] - Fix "redefinition of 'HighResDuration'" / "could not build module 'React'" when building Swift pods with C++ interop against the prebuilt React-Core artifact Pull Request resolved: https://github.com/react/react-native/pull/57575 Test Plan: - New unit tests in `scripts/ios-prebuild/__tests__/headers-spec-test.js`: the excluded header is kept out of the umbrella (fails against the previous code with `Received array: ["React/RCTFrameTimingsObserver.h"]`), and exclusion drift fails closed. - Full ios-prebuild suite: 5 suites, 58/58 tests passing; prettier/eslint clean. - E2E: to be confirmed via a nightly/prebuilt cut building react-native-unistyles in prebuilt mode (`RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1`). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: sammy-SC Differential Revision: D112320697 Pulled By: cipolleschi fbshipit-source-id: 9c7d1d2cb035ac821992914d8df4db7245905834github.com-facebook-react-native · 9847238e · 2026-07-16
- 0.1ETVfix(iOS): prevent UUID collision corrupting Pods project in spm_dependency (#57576) Summary: The first nightly containing the prebuilt/SwiftPM stack (`0.88.0-nightly-20260716`) broke the `react-native-enriched-markdown` job in [react-native-community/nightly-tests](https://github.com/react-native-community/nightly-tests/actions/runs/29476835418/job/87551590732): `pod install` succeeds, but xcodebuild cannot load the generated project: ``` -[XCRemoteSwiftPackageReference _setSavedArchiveVersion:]: unrecognized selector sent to instance Failed to load container at path: .../Pods/Pods.xcodeproj — "The project 'Pods' is damaged and cannot be opened." ``` **Root cause:** `spm_dependency` injects `XCRemoteSwiftPackageReference` / `XCSwiftPackageProductDependency` objects from a `post_install` hook via `project.new(...)`. CocoaPods' `Pod::Project` overrides UUID generation with a deterministic counter scheme (`prefix + %07X counter + trailing 0`) and deliberately skips collision checks, assuming the project is always freshly generated. When the generator counters are out of sync with the loaded object graph, the first generated UUID collides with an existing object — in the observed failure the root `PBXProject`'s own UUID (`46EB2E00000000`). The injected package reference silently overwrites the root object entry in `objects_by_uuid`, so the saved pbxproj's `rootObject` points at the package reference, and Xcode's loader sends `PBXProject`-only messages to it. The bug is latent in `spm_dependency` since its introduction; the recently grown Pods object graph merely exposed it. **Fix:** route object creation through a `new_object` helper that keeps the deterministic counter scheme but probes `generate_uuid` forward past any UUID already present in `objects_by_uuid`. Uniqueness is guaranteed against the live object table regardless of project size/state; `generate_uuid`'s counter is strictly monotonic, so the probe terminates and never repeats within a run. Repeated `pod install`s stay idempotent via the existing find-before-create dedup guards. ## Changelog: [IOS] [FIXED] - Fix "The project 'Pods' is damaged and cannot be opened" when a library uses `spm_dependency` and the generated UUID collides with an existing Pods project object Pull Request resolved: https://github.com/react/react-native/pull/57576 Test Plan: - New standalone test `scripts/cocoapods/__tests__/spm-test.rb` (runs via `ruby scripts/cocoapods/__tests__/spm-test.rb`, uses the real `Pod::Project`): - fresh-project injection (passes before and after — fresh counters don't collide, isolating the trigger), - injection after counter reset (reproduces the corruption against the previous code as `NoMethodError: undefined method 'product_ref_group' for ... XCRemoteSwiftPackageReference` on reload — the Ruby analog of Xcode's crash; passes with the fix), - global UUID uniqueness + clean `Xcodeproj::Project.open` round-trip. - 3 tests, 10 assertions, 0 failures with the fix. - E2E: to be confirmed with a `spm_dependency` library (e.g. react-native-enriched-markdown) in prebuilt mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D112320831 Pulled By: cipolleschi fbshipit-source-id: de190f6492abff2cc6dbd94347e5346d11b50a41github.com-facebook-react-native · 1cdf784a · 2026-07-16
- 0.1ETVfix(iOS): make jsinspector-modern tracing state types move-only for Swift C++ interop (#57605) Summary: The nightly-tests job `[ios] react-native-unistyles` fails on Xcode 26.3 with: ``` error: no matching function for call to '__construct_at' note: in instantiation of member function 'std::vector<...RuntimeSamplingProfile>::vector' requested here note: in implicit copy constructor for 'facebook::react::jsinspector_modern::tracing::TraceRecordingState' first required here ``` while compiling the **Swift** files of the Unistyles pod. The same failure hits any library built with Swift C++ interop (`-cxx-interoperability-mode=default`) — in practice, every Nitro-based library — against the prebuilt React Native core. ### The error `TraceRecordingState` and `HostTracingProfile` hold `std::vector`s of move-only types (`RuntimeSamplingProfile` and `FrameTimingSequence` explicitly delete their copy constructors). Here's the C++ subtlety: `std::vector<T>`'s copy constructor is **declared for every `T`** — it only becomes ill-formed when *instantiated*. So the implicit copy constructors of these two structs are not implicitly deleted; they exist as declared-but-broken constructors that hard-error the moment anything asks for a copy. ### Why React Native compiles fine today Nothing in RN ever asks. Every usage passes these types by reference; the single constructions move. A pure C++ (or ObjC++) build never instantiates the implicit copy constructors, so this code has always compiled — and always would, no matter how much C++ CI you throw at it. The defect is unobservable from within C++. ### What fails, and why now The prebuilt-core headers now ship as real clang modules. A Swift target with C++ interop imports them (directly or transitively — e.g. via a module member whose `#ifdef __cplusplus` body opens because interop builds modules with C++ enabled), and Swift's ClangImporter surfaces the C++ value types to Swift as copyable. When the consumer's generated interop code then uses such a type as a Swift value — for a Nitro-based library, the nitrogen-generated `*_cxx.swift` bridging does exactly this — the compiler **synthesizes a copy of the type, instantiating the ill-formed implicit copy constructor**. That is the "ask" that plain C++ never makes; on Xcode 26.3 it hard-errors the entire module import, killing every Swift file in the consumer. (Newer Swift toolchains treat such types as non-copyable instead of failing.) Before the prebuilt-modules work there was no Swift-visible module containing these headers, so no interop consumer ever imported these types — which is why this surfaces now despite the C++ being unchanged. We deliberately did **not** fix this by removing headers from the module maps: the guarded-C++-in-modules pattern is shared by ~30 legitimately modular headers and is benign in all but this one shape, and experiments showed the type is reachable through multiple independent module surfaces (removing one member just moved the error to the next path). ### The fix Declare the truth: make both types explicitly move-only. ```cpp TraceRecordingState(const TraceRecordingState &) = delete; TraceRecordingState &operator=(const TraceRecordingState &) = delete; TraceRecordingState(TraceRecordingState &&) = default; TraceRecordingState &operator=(TraceRecordingState &&) = default; ``` With the copy constructor explicitly deleted, Swift's importer sees a non-copyable type and imports it as such instead of instantiating a broken copy. It is also simply more correct C++: these types were never copyable in practice, and the explicit deletion turns any future accidental copy into a clear compile error at the call site instead of a template backtrace. Declaring special members makes `HostTracingProfile` a non-aggregate, so its one designated-initializer construction site (`HostTargetTraceRecording.cpp`) is converted to member-wise assignment. A sweep of the affected header surface (`std::vector`/`std::map`/`std::deque` of move-only element types) found exactly these two types; a follow-up adds a `headers-verify.js` gate that imports the shipped modules under Swift C++ interop at prebuild time, so the next type with this shape fails RN's own CI instead of community nightlies. ## Changelog: [IOS] [FIXED] - Fix Swift C++-interop build failure (implicit copy constructor of TraceRecordingState/HostTracingProfile) for libraries using cxx interop with prebuilt React Native core Pull Request resolved: https://github.com/react/react-native/pull/57605 Test Plan: On a fresh RN-nightly app with stock `react-native-unistyles@3.3.0` + `react-native-nitro-modules`, prebuilt core (`RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1`), Xcode 26.3: - **Red**: stock headers reproduce the CI failure exactly (`__construct_at` → `TraceRecordingState`). Fixing only `TraceRecordingState` then surfaces the identical failure on `HostTracingProfile` — confirming the shape, not the type, is the bug. - **Green**: with both headers fixed (stock module maps, nothing else changed): BUILD SUCCEEDED — zero `__construct_at`, zero `shadowNodeFromValue`, zero module errors. - All RN-internal usages audited: references and moves only; no behavior change. Plain C++/ObjC++ compilation unaffected by construction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D112802806 Pulled By: cipolleschi fbshipit-source-id: d2ae201c1fbb4de040f51ebc88263c7347b5979bgithub.com-facebook-react-native · 38611186 · 2026-07-21
- 0.1ETVfix(cocoapods): escape local file URIs for unicode paths (#56907) Summary: https://github.com/facebook/react-native/issues/56878 shows that using unicode characters in paths fails with pod install. Expo fixed this internally here: https://github.com/expo/expo/pull/45779 Fixes https://github.com/facebook/react-native/issues/56878 ## How: Build local `file://` sources through a shared helper that percent-encodes filesystem paths before passing them to `URI::File.build`. This avoids Ruby/CocoaPods URI failures when React Native projects or local prebuilt tarballs live under paths containing Unicode characters or spaces. Apply the helper to `RNCore` and `ReactNativeDependencies` local tarball sources, including RNCore dSYM-processed prebuilt paths, while leaving remote Maven and Sonatype URLs unchanged. Add focused coverage for Unicode, spaces, ASCII paths, and the raw `URI::File.build` regression case. ## Changelog: [IOS] [FIXED] - fixed escaping local file URIs for unicode paths in ruby scripts Pull Request resolved: https://github.com/facebook/react-native/pull/56907 Test Plan: - Test with creating a new project in a path containing a unicode character and the run pod install. Reviewed By: cortinico Differential Revision: D105968728 Pulled By: cipolleschi fbshipit-source-id: 6d5b9043aafe3d86494f3b5ca0f208e46f1f3739github.com-facebook-react-native · 9563cb5b · 2026-05-22
- 0.0ETVfix(cocoapods) Podfile.lock SPEC CHECKSUMS drift for React XCFrameworks (#56803) Summary: Two developers (or one developer on two paths, or CI vs. local) running pod install on the same React Native project at the same commit get different SPEC CHECKSUMS entries for React-Core-prebuilt and ReactNativeDependencies in Podfile.lock. That breaks pod install-deployment style verification and any workflow that expects Podfile.lock to be reproducible. CocoaPods derives each SPEC CHECKSUMS entry by hashing the in-memory podspec JSON. So anything embedded in source.http, prepare_command, user_target_xcconfig, etc. becomes part of the hash. Two podspec-resolution sites in this repo build their source.http from an absolute on-disk path. Because project_pods_root is an absolute path, the resulting file://<abs>/... URL differs across machines or working-tree paths, so the hashed JSON differs, so the checksum differs. ### How The Maven URL for each tarball is already computed inside both functions (stable_tarball_url(...) / nightly_tarball_url(...) / release_tarball_url(...)). Returning that URL — a stable string identical across machines — instead of the local file:// URL makes source.http path-free. CocoaPods downloads from Maven and caches the tarball itself, so functionality is preserved. The pre-existing local-tarball download is kept untouched (its only remaining consumer is the opt-in `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1` dSYM-injection path in rncore.rb, which still needs file:// to feed CocoaPods a mutated tarball — gated by unless @download_dsyms so the leak is preserved only for that flag). **Out of scope: ** hermes-engine.podspec has the same shape of leak in user_target_xcconfig.HERMES_CLI_PATH. Fixing it requires a paired change to ensure hermesc lands at the new ${PODS_ROOT}-relative path; that's a separate PR. ## Changelog: [IOS] [FIXED] - Fix Pod install checksum drifting Pull Request resolved: https://github.com/facebook/react-native/pull/56803 Test Plan: Run `pod install` and verify that none of the following files contains absolute paths: - Pods/Local Podspecs/React-Core-prebuilt.podspec.json - Pods/Local Podspecs/ReactNativeDependencies.podspec.json Reviewed By: christophpurrer Differential Revision: D104889112 Pulled By: CalixTang fbshipit-source-id: 97505a8bf78f7df57bda2d87705da5a20c934d2bgithub.com-facebook-react-native · 814ebb12 · 2026-05-13