Skip to content

chore: upgrade React Native to 0.87.1 - #1662

Open
riteshshukla04 wants to merge 3 commits into
margelo:mainfrom
riteshshukla04:chore/upgrade-react-native-0.87.1
Open

riteshshukla04 wants to merge 3 commits into
margelo:mainfrom
riteshshukla04:chore/upgrade-react-native-0.87.1

Conversation

@riteshshukla04

Copy link
Copy Markdown
Member

RN upgrade

- Bump react-native and @react-native/* from 0.85.3 to 0.87.1 in the root,
  apps/example, apps/benchmark, the workspace packages and packages/template
- Align apps/benchmark's React Native CLI with the template (20.2.0) so only
  one CLI version is installed
- Apply the rn-diff-purge 0.85.3 -> 0.87.1 template changes: Gradle 9.4.1,
  AGP 9 opt-outs, edge-to-edge, compileSdk/buildTools 37, Kotlin 2.2.0,
  proguard-android-optimize, tsconfig; engines.node from the template
- Bump react-native-screens (^4.28.0) and react-native-safe-area-context
  (^5.10.0) for RN 0.87 support, and react-native-worklets (^0.12.2)
- Adopt the UIScene lifecycle (SceneDelegate) in both apps, following the
  RN 0.88 template, so they launch on iOS 27
- Use objc Swift interop in the benchmark app target, like the example app
- Type the NativeComponentRegistry deep import via its public export
  (RN 0.87 Strict TypeScript API) while keeping RN 0.78+ runtime support
- Cast SegmentedControl, whose types rely on the removed NativeMethods

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 26, 2026

Copy link
Copy Markdown

@riteshshukla04 is attempting to deploy a commit to the Margelo Team on Vercel.

A member of the Team first needs to authorize it.

@riteshshukla04

Copy link
Copy Markdown
Member Author

I had to do few uncoventional things.

  1. Scene Delegate migration .This will else crash the app on startup on xcode 27 and ios 27. The changes in templates land in 0.88-rc-2 (https://react-native-community.github.io/upgrade-helper/?from=0.85.3&to=0.88.0-rc.2)
  2. Do some dirty typescript hacks to support 0.87 strict apis .

riteshshukla04 and others added 2 commits September 27, 2026 22:55
…d with react-native 0.87+

Since react-native 0.87, `react::Props` no longer populates `rawProps` in its
constructor - only `ConcreteComponentDescriptor::cloneProps` does. Nitro's
`ViewComponentDescriptor` overrides `cloneProps`, so on Android (which sends
`rawProps` to the Java `ViewManager`) Nitro Views never received base View props
such as `testID`, breaking the views harness tests.

Call `ShadowNode::initializeDynamicProps` like the base implementation does,
only when it exists (RN_SERIALIZABLE_STATE / newer react-native versions).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGP 9 (react-native 0.87 template) no longer accepts `Provider` instances in the
Android SourceSet API, so the `nitroSanitizer=address` build failed while
evaluating `apps/example/android/app/build.gradle`. Pass the resolved
directories instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@mrousavy mrousavy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! but few nits

Comment on lines +29 to +32
// React Native 0.87 removed `NativeMethods` from its public types, which breaks
// this package's class intersection even though its props remain compatible.
const SegmentedControl =
SegmentedControlNative as unknown as React.ComponentType<SegmentedControlProps>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that's not good. Let's wait or fix in there, as unknown as T is definitely the wrong approach.

Comment on lines -50 to +57
return TShadowNode::Props(context, /* & */ rawProps, props);
auto shadowNodeProps = TShadowNode::Props(context, /* & */ rawProps, props);
// 3. Accumulate `Props::rawProps` (only exists with `RN_SERIALIZABLE_STATE`, e.g. on Android), which are sent to the
// Java `ViewManager` - base View props like `testID` depend on it. Since react-native 0.87, `Props` no longer does
// this in its constructor, only `react::ConcreteComponentDescriptor::cloneProps` does - so we do the same here.
if constexpr (requires { TShadowNode::initializeDynamicProps(shadowNodeProps, rawProps, props); }) {
TShadowNode::initializeDynamicProps(shadowNodeProps, rawProps, props);
}
return shadowNodeProps;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this PR is now too big - it no longer just upgrades to RN 0.87, but it also changes core logic in Views. De-couple and stack as multiple PRs please.

Comment on lines 8 to +20
// TODO: Migrate to the official export of `NativeComponentRegistry` from `react-native` once react-native 0.83.0 becomes more established as this is deprecated
// @ts-expect-error: Since react-native 0.87 (Strict TypeScript API). Hack for now
// eslint-disable-next-line @react-native/no-deep-imports
import * as NativeComponentRegistry from 'react-native/Libraries/NativeComponent/NativeComponentRegistry'
import * as UntypedNativeComponentRegistry from 'react-native/Libraries/NativeComponent/NativeComponentRegistry'
import type {
HybridView,
HybridViewMethods,
HybridViewProps,
} from './HybridView'

const NativeComponentRegistry: typeof PublicNativeComponentRegistry =
UntypedNativeComponentRegistry

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also sucks. Let's just use the import NativeComponentRegistry from 'react-native' now, which breaks on older RN versions but it's the better way forward. Remove the unsafe and untyped stuff - but again; separate stacked atomic PRs please.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants