Repository navigation
Description
Upgrade React Native (RN) to the Latest Version for Enhanced Performance and Compatibility
Background
Over time, our codebase has grown to include numerous custom patches, and the open-source ecosystem around React Native continues to evolve with frequent updates, performance improvements, and new features. Third-party libraries often adapt quickly to these changes.
Expo SDK 58 upgrades React Native from 0.86 straight to 0.88, so it picks up the changes from both RN 0.87 and RN 0.88 in one step. RN 0.88 is classified as a non-breaking release, but RN 0.87 is a large cleanup release that removes many deprecated APIs and makes the Strict TypeScript API the default. See the Expo SDK 58 beta changelog.
SDK 58 is still in beta (expo@58.0.0-preview.3, bundling react-native@0.88.0-rc.0) and goes stable shortly after RN 0.88 ships. This issue is on HOLD until then.
This follows Upgrade RN to 0.86 and Expo SDK 57, which is now deployed to production.
Problem
Staying on RN 0.86 / Expo SDK 57 delays compatibility with the latest Expo ecosystem, misses two releases of RN fixes and performance work, and leaves us on bundled dependency versions that SDK 58 has already validated together. The RN 0.87 Strict TypeScript API opt-out only exists through RN 0.88, so the migration work gets harder the longer we wait.
Solution
- Upgrade React Native to 0.88 and Expo SDK to 58
- Upgrade prerequisite dependencies bundled with SDK 58 (see table below) before the main bump PR
- Audit and remove unnecessary patches
- Coordinate parallel PRs in App (NewDot) and Mobile-Expensify (OldDot / HybridApp)
- Conduct thorough testing for stability across web, iOS, and Android
Prerequisite dependency upgrades (file as sub-issues when work begins)
SDK 58 bundles newer versions of these libraries. Follow the RN 0.86 / SDK 57 pattern: land each on current RN 0.86 / SDK 57 before the main bump.
| Dependency | Current (main) |
SDK 58 target | Notes |
|---|---|---|---|
react-native-worklets |
0.11.1 |
0.12.2 |
Upgrade first; version alignment with reanimated is critical |
react-native-reanimated |
4.5.5 |
4.6.0 |
After worklets |
react-native-gesture-handler |
2.32.0 |
~3.2.1 |
Major version bump, expect breaking API changes |
react-native-webview |
13.16.0 |
14.0.1 |
Major version bump; we carry a patch on this package |
@react-native-community/netinfo |
11.4.1 |
12.0.1 |
Major version bump |
react-native-screens |
4.25.0 |
~4.27.0 |
We carry a patch on this package |
react-native-safe-area-context |
5.6.2 |
~5.9.1 |
We carry a patch on this package |
react-native-keyboard-controller is already on 1.22.4, which is what SDK 58 bundles, so it needs no prerequisite upgrade this time.
Known blockers and native work
- iOS 27 SDK and the UIScene lifecycle. SDK 58 requires the scene based lifecycle and generates a
SceneDelegate.ios/NewExpensify.xcodeprojhas noSceneDelegatetoday and targets iOS 16.4. This needs native work in both App and Mobile-Expensify for HybridApp. - Strict TypeScript API is the default in RN 0.87. Deep imports from
react-native/Libraries/*become type errors.mainhas roughly 15 of them acrosssrc/andtests/, mostlyStyleSheetTypesandCoreEventTypes, plus several insidepatches/. Thereact-native-legacy-deep-importscustomConditionsopt-out only lasts through RN 0.88, so we should migrate rather than opt out. - Android toolchain. RN 0.87 wants
compileSdkVersionandbuildToolsVersionat 37.android/build.gradlecurrently sets 36 withkotlinVersion = "2.1.20". AGP 9 support is new and needsandroid.builtInKotlin=falseandandroid.newDsl=false. - RN 0.88 TurboModule ArrayBuffer change. Codegen now emits
RCTArrayBuffer *instead ofNSMutableData *for TurboModule methods taking or returning anArrayBuffer. This affects our nitro modules and any local TurboModule using ArrayBuffer. - Removed APIs. A pass over
mainfound no use ofInteractionManager,ImageBackground, theModalanimatedprop, or a booleankeyboardShouldPersistTaps. The removal of theStatusBarbackgroundColorandtranslucentprops still needs a review ofsrc/libs/StatusBar/. - Patches.
patches/holds 56 entries, including patches onreact-native,react-native-reanimated,react-native-screens,react-native-safe-area-context,react-native-web, andreact-native-webview. Each needs a rebase or removal.
Node is already on 26.5.0, so the RN 0.87 floor of Node 22.13.0 is met.
Issue Owner
Current Issue Owner: @shubham1206agraMetadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsHIGH
Activity
roryabraham commentedon Sep 17, 2026
@MelvinBot which of the prerequisite dependency upgrades can we land on RN 0.86? Create sub-issues for each of the prerequisite dependency upgrades that we can land before RN 0.86. Mark react-native-reanimated as blocked by react-native-worklets
45 remaining items
melvin-bot commentedon Nov 8, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Nov 8, 2026
Payment Summary
Resolving PRs:
Bump @rnmapbox/maps to 10.3.10 #105006
Bump react-native-blob-util to 0.24.12 #105004
Reviewer: @shubham1206agra owed $1000 via NewDot
Contributor: @war-in does not require payment (Contractor)
Contributor: @jakubstec does not require payment (Contractor)
Contributor: @collectioneur does not require payment (Contractor)
BugZero Checklist (@mallenexpensify)
mitarachim commentedon Nov 10, 2026
Deploy Blocker #106439 was identified to be related to the PR #106096 that attempted to fix this issue.
[-][Due for payment 2026-11-09] [$1000] Upgrade RN to 0.88 and Expo SDK 58[/-][+][Due for payment 2026-11-18] [$1000] Upgrade RN to 0.88 and Expo SDK 58[/+]melvin-bot commentedon Nov 11, 2026
@shubham1206agra @mallenexpensify
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.35-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-11-18. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]