Support React Native 0.87 on 2.x - #4497
Conversation
Currently we use TypeScript 5. Starting from 0.87, React Native uses TyoeScript 6. I think it is good time to adapt to these changes and bump it in our repository. I've left docs since they are not part of workspaces. - `yarn ts-check` - Installed Gesture Handler from generated package (cherry picked from commit 17d3df8)
Since React Native 0.87, Strict TS API is [enabled by default ](react/react-native#57490). This PR brings necessary changes to resolve ts-errors on 0.87. This PR also removes `cursor: undefined;` from `iOS`, but now it is a valid prop - this workaround was necessary on old arch `yarn ts-check` (cherry picked from commit 7d2f321)
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (44)
💤 Files with no reviewable changes (5)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe pull request updates the repository for React Native 0.87, Reanimated 4.6, Worklets 0.12, and TypeScript 6. It adds the React Native 0.87 iOS JSI integration and updates gesture-handler types, codegen imports, build settings, and example applications. ChangesToolchain and example alignment
Sequence Diagram(s)sequenceDiagram
participant RNGestureHandlerModule
participant ReactNative087
participant JSIRuntime
RNGestureHandlerModule->>ReactNative087: register RCTTurboModuleWithJSIBindings
ReactNative087->>RNGestureHandlerModule: installJSIBindingsWithRuntime
RNGestureHandlerModule->>JSIRuntime: decorateRuntime(runtime)
Merge Risk: ⚪ Minimal · up to No actionable merge-blocking risk is established for the current changes. 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🟡 Changes recommended
The Pressable ref changes treat ref as a normal prop without React.forwardRef, so consumer refs won’t actually be forwarded and the new API surface is misleading.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the 2.x line to build and typecheck against React Native 0.87, aligning native iOS integration changes with RN’s removal of old-arch headers and adopting TypeScript 6 + Strict TS API type adjustments across the library and examples.
Changes:
- Update iOS new-arch JSI binding installation for RN 0.87 and remove an obsolete React header import.
- Switch the repo to TypeScript 6.0.3 and adjust type definitions/specs to comply with RN 0.87’s exports + Strict TS API.
- Bump example apps and tooling dependencies (RN 0.87.1, Reanimated/Worklets) and add an Expo modules patch via Yarn resolutions.
File summaries
| File | Description |
|---|---|
| yarn.config.cjs | Bump shared Reanimated/Worklets versions |
| tsconfig.json | Switch moduleResolution to bundler |
| packages/react-native-gesture-handler/tsconfig.build.json | Set rootDir to src |
| packages/react-native-gesture-handler/src/specs/RNGestureHandlerRootViewNativeComponent.ts | Use public codegenNativeComponent typing |
| packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts | Update CodegenTypes + HostComponent cast |
| packages/react-native-gesture-handler/src/specs/NativeRNGestureHandlerModule.ts | Use CodegenTypes.Double in spec |
| packages/react-native-gesture-handler/src/mocks/mocks.tsx | Add explicit component type casts |
| packages/react-native-gesture-handler/src/components/touchables/TouchableOpacity.tsx | Lint adjustment for unbound-method |
| packages/react-native-gesture-handler/src/components/touchables/TouchableNativeFeedback.android.tsx | Tighten return typing / prop cast |
| packages/react-native-gesture-handler/src/components/touchables/TouchableHighlight.tsx | Style composition type workaround |
| packages/react-native-gesture-handler/src/components/Text.tsx | Ref type to ComponentRef |
| packages/react-native-gesture-handler/src/components/Swipeable.tsx | Cast to satisfy interpolate overloads |
| packages/react-native-gesture-handler/src/components/ReanimatedDrawerLayout.tsx | Lint adjustment for unbound-method |
| packages/react-native-gesture-handler/src/components/Pressable/PressableProps.tsx | Ref type change in props |
| packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx | Attempt to pass ref through |
| packages/react-native-gesture-handler/src/components/GestureHandlerButton.web.tsx | Add explicit forwardRef component type |
| packages/react-native-gesture-handler/src/components/GestureComponents.tsx | Ref types + DrawerLayoutAndroid typing |
| packages/react-native-gesture-handler/package.json | Bump RN, TS, Reanimated/Worklets devDeps |
| packages/react-native-gesture-handler/apple/RNGestureHandlerModule.mm | RN 0.87 JSI binding install path |
| packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm | Remove obsolete RCTRootContentView import |
| package.json | Bump TS + add Expo modules patch resolution |
| apps/macos-example/tsconfig.json | Remove baseUrl (inherit root config) |
| apps/macos-example/package.json | Bump TypeScript version |
| apps/expo-example/tsconfig.json | Remove baseUrl (inherit root config) |
| apps/expo-example/package.json | Pin Expo + bump deps/TS |
| apps/common-app/tsconfig.json | Remove baseUrl (inherit root config) |
| apps/common-app/src/showcase/bottomSheet/index.tsx | Animated generic type adjustments |
| apps/common-app/src/release_tests/touchables/index.tsx | Update background prop typing |
| apps/common-app/src/release_tests/nestedFling/index.tsx | Animated generic type adjustments |
| apps/common-app/src/release_tests/combo/index.tsx | ComponentRef-based ScrollView ref type |
| apps/common-app/src/recipes/scaleAndRotate/index.tsx | Animated generic type adjustments |
| apps/common-app/src/recipes/panAndScroll/index.tsx | Animated generic type adjustments |
| apps/common-app/src/new_api/calculator/index.tsx | ComponentRef-based ScrollView refs |
| apps/common-app/src/ListWithHeader/ListWithHeader.tsx | Avoid mutating flattened style object |
| apps/common-app/package.json | Bump Reanimated/Worklets + TS |
| apps/basic-example/tsconfig.json | Remove baseUrl/types override |
| apps/basic-example/src/Navigator.tsx | Remove unnecessary unbound-method disable |
| apps/basic-example/package.json | Bump RN 0.87.1 + toolchain deps |
| apps/basic-example/ios/Podfile.lock | Update iOS pods for RN 0.87 |
| apps/basic-example/ios/BasicExample/PrivacyInfo.xcprivacy | Swap privacy accessed API entries |
| apps/basic-example/android/gradlew | Pin Gradle template source URL |
| apps/basic-example/android/gradle/wrapper/gradle-wrapper.properties | Bump Gradle distribution version |
| apps/basic-example/android/gradle.properties | Enable edge-to-edge + AGP opt-outs |
| apps/basic-example/android/build.gradle | Bump SDK/buildtools/Kotlin versions |
| apps/basic-example/android/app/build.gradle | Use optimized Proguard default file |
| .yarn/patches/expo-modules-core-npm-56.0.25-a715438de2.patch | Patch executeSync -> runSync |
Review details
- Files reviewed: 44/48 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| accessible, | ||
| simultaneousWithExternalGesture, | ||
| requireExternalGestureToFail, | ||
| blocksExternalGesture, | ||
| ref, |
| /** | ||
| * A reference to the pressable element. | ||
| */ | ||
| ref?: React.Ref<View>; | ||
| ref?: React.Ref<React.ComponentRef<typeof View>>; | ||
|
|
Description
Brings React Native 0.87 support to the 2.x line. Mirrors the changes already on main (#4247, #4310, #4311, #4319), trimmed to what the v2 code needs.
Native (iOS):
RCTRootContentView.himport. The header is gone from the prebuilt React-Core framework in 0.87.RCTCxxBridgeno longer exists, so theisViewFlatteningDisabledJSI binding is now installed viaRCTTurboModuleWithJSIBindings. Gated behindREACT_NATIVE_MINOR_VERSION >= 87, older versions keep the previous code path.TypeScript:
moduleResolutiontobundler. RN 0.87 exposes its types only through the packageexportsmap.CodegenTypesnamespace and publiccodegenNativeComponentin specs,ComponentRef-based ref types in Pressable, Text, GestureComponents, style fixes in touchables.mocks.tsxandGestureHandlerButton.web.tsx. TS 6 refuses to emit declarations that reach RN's non-exported type aliases.Swipeablewhereinterpolateoverloads on aValue | AnimatedInterpolationunion no longer unify.unbound-methodlint adjustments for methods RN 0.87 now types as class members.Example apps:
basic-exampleto RN 0.87.1, Reanimated 4.6.0, Worklets 0.12.1.expoto 56.0.21 and patchexpo-modules-core56.0.25 (executeSync->runSync), which Worklets 0.12 removed. The resolution is keyed on the range expo declares, so the exact pin keeps the patch applying.common-appexamples for the 0.87 types.Test plan
yarn ts-check,yarn lint-js,yarn jestbasic-exampleon iOS and Androidexpo-exampleon iOS and Android