Skip to content

NativeModules.RNPurchases is null on React Native 0.81 + Expo SDK 54 with New Architecture enabled #1739

@cjmaret

Description

@cjmaret

Describe the bug
A clear and concise description of what the bug is. The more detail you can provide the faster our team will be able to triage and resolve the issue. Do not remove any of the steps from the template below. If a step is not applicable to your issue, please leave that step empty.

NativeModules.RNPurchases is null at runtime. The SDK cannot be configured and all calls throw:

Error: There is no singleton instance. Make sure you configure Purchases before trying to get the default instance.

1. Environment

  1. Platform: iOS
  2. SDK version: react-native-purchases 10.0.1, react-native-purchases-ui 10.0.1
  3. OS version: iOS 18
  4. Xcode version: 16
  5. React Native version: 0.81.5
  6. SDK installation: CocoaPods (via npx expo install + pod install)
  7. How widespread: 100% of devices when running Expo SDK 54 + expo-router 6.x with New Architecture enabled

2. Debug logs that reproduce the issue
WARN [RevenueCat] isConfigured() returning false: Native module not available
ERROR [RevenueCat] configure failed: [TypeError: Cannot read property 'setLogLevel' of null]
ERROR [Paywall] getOfferings error: [Error: There is no singleton instance. Make sure you configure Purchases before trying to get the default instance. https://errors.rev.cat/configuring-sdk]

4. Steps to reproduce, with a description of expected vs. actual behavior

  1. Create an Expo SDK 54 app using expo-router 6.x (follows RC's own Expo installation guide at https://www.revenuecat.com/docs/getting-started/installation/expo)
  2. Install react-native-purchases and react-native-purchases-ui via npx expo install
  3. Run pod install and build with npx expo run:ios
  4. Call Purchases.configure({ apiKey }) on app startup

Expected:

  • SDK configures successfully, getOfferings() and purchasePackage() work normally.

Actual:

  • NativeModules.RNPurchases is null. configure() throws Cannot read property 'setLogLevel' of null. All subsequent SDK calls throw "no singleton instance."

Root cause:

  • react-native-purchases uses RCT_EXPORT_MODULE() (old bridge). In RN 0.81 + Expo SDK 54 with New Architecture, old bridge modules are not registered. the generated RCTModuleProviders.mm does not include RNPurchases, so NativeModules.RNPurchases is null at runtime.

New Architecture cannot be disabled: expo-router@6.0.22 depends on react-native-reanimated@4.1.6, which throws a hard error at startup if New Architecture is not enabled ([Reanimated] Reanimated requires the New Architecture). There is no escape from this dependency chain in Expo SDK 54.

  1. Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)Additional context
    Add any other context about the problem here.

The react-native-purchases iOS source (RNPurchases.m) registers the module with RCT_EXPORT_MODULE() only. There are no TurboModule codegen specs (no .js.flow or NativeModule*.ts spec files), so the module is invisible to the New Architecture module provider system.

Confirmed by inspecting the generated ios/build/generated/ios/RCTModuleProviders.mmRNPurchases is absent.

Temporary workaround: patching dist/utils/environment.js to return true from shouldUseBrowserMode() when NativeModules.RNPurchases is null, which enables the HTTP-based browser mode. This unblocks development with the RevenueCat Test Store but does not support real App Store purchases.

The fix requires adding TurboModule support to react-native-purchases so the native module is registered via the New Architecture module provider system.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions