Skip to content

refactor: rn 0.87 compatibility - #3786

Merged
isekovanic merged 2 commits into
developfrom
refactor/rn-0.87-support
Aug 26, 2026
Merged

refactor: rn 0.87 compatibility#3786
isekovanic merged 2 commits into
developfrom
refactor/rn-0.87-support

Conversation

@isekovanic

@isekovanic isekovanic commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

🎯 Goal

Support React Native 0.87.

0.87 makes the Strict TypeScript API the default and drops several types from the root react-native export, which breaks our type-check. Its Babel preset also miscompiles one of our shipped files.

The SDK now builds, type-checks and runs on both 0.86 and 0.87. Peer range (>= 0.76.0) naturally remains unchanged, no public API removed.

🛠 Implementation details

Strict TypeScript API - new src/types/react-native-compat.ts exporting ViewRef/TextInputRef/ScrollViewRef/FlatListRef etc. as React.ComponentRef<typeof X>. The "fix" is in the semantics, as it resolves to the old class-instance types on <= 0.86 and the new ones on 0.87, so we keep the 0.76 floor. Using RN's own *Instance names would have dropped everything below 0.87. Same file redeclares KeyboardEventListener, ViewToken and ViewabilityConfig, which 0.87 no longer exports.

API shape changes - useColorScheme() and findNodeHandle() have become nullable, AppState.currentState widened to string | null | undefined, FlatList's data and ListFooterComponent have stopped accepting null, style objects have become Readonly, NativeEventEmitter has become generic. onAccessibilityAction moved to ViewProps.

Type leaks - explicit annotations on Input, useAnimatedGalleryStyle, SafeAreaViewWrapper and ImageGalleryFooter, plus a ThemeStyle union, to stop RN-internal names leaking into lib/typescript.

SqliteClient runtime fix - statics were arrow class fields calling this.foo(). 0.87's Babel preset hoists that to a module-level var _this = this, so lib/commonjs shipped calls against the wrong object and threw. Now references the class explicitly.

Build config - both wrappers' tsconfig.json opt into legacy deep-import types (the codegen spec must keep the deep codegenNativeComponent import; the root export only exists from 0.80). Android: Java 1.8 => 17, Kotlin 1.7 => 2.2, minSdk 21 => 24, compileSdk fallback 31 => 34.

compileSdk is 34 rather than 37 on purpose, as 0.87's react-android declares minCompileSdk=34 and a library's compileSdk caps what we may call, it isn't a floor on integrators. It's only reached when the app doesn't set rootProject.ext.compileSdkVersion, which basically any app always does.

Jest - two moduleNameMapper shims, both third-party:

For our integration tests to work I had to do some mental gymnastics to get everything off the ground.

  • react-native-svg (<= 15.15.5) reads Touchable.Mixin off the RN root. 0.87 keeps that export alive for exactly this call site but installs it late and non-enumerably, so Babel's ESM interop drops it under Jest.
  • reanimated 4.6.0's initializeReanimatedModule() calls setCSSEventHandler() unconditionally, which throws on the JS only backend Jest uses.

moduleNameMapper rather than jest.mock('react-native', …) because it's resolver-level, so it also covers the separate registry Jest builds for automocks and it doesn't shadow per suite RN mocks.

Example apps - SampleApp gets the AGP 9 proguard fix (proguard-android-optimize.txt; AGP 9 rejects proguard-android.txt outright and since it's evaluated at configuration time it breaks the debug build too), AGP 9 opt-outs, SDK 37/36, and 13 strict-API fixes in its own code. ExpoMessaging deliberately stays on Expo 57 / RN 0.86 for now, while Expo 58 remains canary only and holding it back doubles as backwards-compat coverage for now. Once 58 ships we can likely bump that too pretty easily.

Native source - no changes. None of 0.87's removed native APIs are used, headers already use the namespaced <React/...> form, and StreamShimmerViewComponentView already sets _props = defaultProps in initWithFrame — the thing 0.87 now asserts on.

🎨 UI Changes

🧪 Testing

☑️ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

@Stream-SDK-Bot

Copy link
Copy Markdown
Contributor

SDK Size

title develop branch diff status
js_bundle_size 1997 KB 2031 KB +34472 B 🔴

@isekovanic
isekovanic merged commit a72b6b3 into develop Aug 26, 2026
10 of 11 checks passed
@isekovanic
isekovanic deleted the refactor/rn-0.87-support branch August 26, 2026 08:36
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.

3 participants