Repository navigation
feat(mobile): turn on the React Native New Architecture - #14657
dylanjeffers wants to merge 1 commit into
Conversation
- Android newArchEnabled=true - iOS RCTNewArchEnabled true in both Info.plists - pod install with RCT_NEW_ARCH_ENABLED=1 in CI and postinstall - Podfile.lock regenerated for the Fabric/codegen pods - MainApplication.reactHost built once (lazy) so CodePush.getJSBundleFile() isn't re-read on every access Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Dependency limit exceeded — report not shown. This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report. Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard. Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account. |
…st effect (#14658) ## Summary Cold launches can stay on the splash screen forever. `App` renders `null` until the AsyncStorage preload finishes, and its `useEffectOnce` only subscribed to `localStoragePreloadPromise` when the module-level `localStoragePreloaded` flag was still false. If the preload resolves after the first render but before the effect runs, the flag is already true, the effect skips the subscription, and nothing ever sets `preloaded`. `App` keeps returning `null`, `RootScreen` never mounts, and `BootSplash.hide` is never called. The fix subscribes unconditionally. `setPreloaded(true)` is idempotent, so the extra `.then` on an already-resolved promise costs nothing. ## Why now Found while smoke-testing the New Architecture flip (#14657). On the new architecture, passive effects run later relative to the first render, which opens the window. On the iOS 26.5 simulator with the 1.5.189 new-arch Release build: - without this fix, 5 of 6 cold launches of the as-built bundle stuck on the splash (JS idle, `RCTRootComponentView` with no children). Instrumented runs logged `App render preloaded=false`, then `preload resolved`, and no further render. - with this fix, 8 of 8 cold launches reached the feed. The same race exists on the old architecture (introduced in #14259). It just loses it less often. 3 of 3 old-arch 1.5.188 launches were fine. ## Rollout JS-only. It's safe to OTA to 1.5.188. It has to be on main before #14656 / #14657 merge, so the 1.5.189 binary ships with it. Rebase or merge main into `chore/mobile-native-release-1.5.189` after this lands. ## Checks - eslint `packages/mobile/src/app/App.tsx`: pass - `npx tsc --noEmit -p packages/mobile`: pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Turns on React Native's New Architecture (Fabric + bridgeless) for native release 1.5.189, with nothing else changing. It's based on #14656 (the version bump). Everything the flip needs shipped on the old architecture in 1.5.188: RN 0.81.6, the RNTP bridgeless patch (#14647), native-driver progress (#14651), react-native-svg 15.15.1 + Lottie
shouldBeRecycled NO(#14652), the SwiftAudioEx Podfile patch (#14650), notifee (#14640) and UIScene (#14626). This supersedes the spike (#14648), whose findings matrix still applies.Requires #14658 first. On new arch, about half of iOS cold launches stayed on the splash screen. This is a JS race in
App.tsx's preload gate, and it isn't new-arch code. Details are below and in #14658.What changed
packages/mobile/android/gradle.properties:newArchEnabled=trueRCTNewArchEnabledtruein every Info.plist that has the key:AudiusReactNative/Info.plistandRichPushExtension/Info.plistRCT_NEW_ARCH_ENABLED=0→1in every placegit grepfinds it: bothpod installsteps in.github/workflows/mobile.ymlandscripts/postinstall.sh. Set to 1, not removed. RN 0.81's CocoaPods default is already new arch when the variable is unset (ENV["RCT_NEW_ARCH_ENABLED"] == '0' ? false : true), but with an explicit1, a staleRCT_NEW_ARCH_ENABLED=0exported in someone's shell or a CI env can't silently build an old-arch binary. It also matches the explicit Info.plist keys.Podfile.lockregenerated withRCT_NEW_ARCH_ENABLED=1 bundle exec pod install: Fabric/codegen subspecs and checksums. The Podfile checksum is unchanged.MainApplication.kt:reactHostis nowby lazy { getDefaultReactHost(applicationContext, reactNativeHost) }. It was a getter, and theReactNativeHostoverload ofgetDefaultReactHostevaluatesreactNativeHost.jsBundleFile(soCodePush.getJSBundleFile()) on every access, even though the host itself is cached. With the lazy property, logcat shows one[CodePush] Loading JS bundleline per session. The spike saw 33.android:enableOnBackInvokedCallback="false"stays inAndroidManifest.xml. Predictive back is a separate change.android/build.gradle'sdr.pogodin_react-native-fsblock. It only applies whennewArchEnabled != 'true', so it goes inert.Checks
npx tsc --noEmit -p packages/mobileplutil -linton both plists,bash -n scripts/postinstall.shand a YAML parse ofmobile.ymlpass. #14658'sApp.tsxpasses eslintcd packages/mobile && npm testRCT_NEW_ARCH_ENABLED=1 bundle exec pod install,ENVFILE=.env.prod,generic/platform=iOS Simulator,ARCHS=arm64, worktree-local DerivedDataRCTNewArchEnabled=true, bundle carries 1.5.189assembleProdRelease -PreactNativeArchitectures=arm64-v8a, debug keystorelibappmodules.sopresent, signedCN=Android DebugiOS smoke test (RN081 iOS 26.5 simulator, signed in, Release)
Installed over the signed-in 1.5.188 app. The CodePush folder was moved aside before every launch. Old-arch numbers are the 1.5.188 Release build on the same simulator and account, measured just before.
sampleshows thecom.facebook.react.runtime.JavaScriptthread (old arch:com.facebook.react.JavaScript)RCTRootComponentViewhad no children (lldbrecursiveDescription). Instrumented runs loggedApp render preloaded=false→preload resolved→ no re-render. Fixed by #14658top -laverage, two runs eachAndroid (emulator,
Release189_API_36, clone ofAudius_API_36, swiftshader, 4 GB)pm clear, then launch: logcat shows[CodePush] Loading JS bundle from "assets://index.android.bundle"once. No "Legacy Architecture" warning.libfabricjni/libreact_newarchdefaultsload, with noFATAL EXCEPTION.Not verified
ShadowTree::commitassert.🤖 Generated with Claude Code