Description
Description
While investigating why the compatibility layer was not working for react-native-netinfo when bridgeless mode was tuned on, I noticed that they were using the spread operator (...
) directly on the object returned from React Native's NativeModules
e.g.
import {NativeModules} from 'react-native';
const RNCNetInfo: NetInfoNativeModule = NativeModules.RNCNetInfo;
export default {
...RNCNetInfo,
get eventEmitter(): NativeEventEmitter {
...
}
}
This is not a problem when bridgeless mode is tuned off, but as soon as bridgeless mode is tuned on, trying to access any of the module functions will result in an unhandled promise rejection

Upon some investigation, I noticed that this same error also happens if we try to use the spread operator over a turbo module (with bridgeless mode on and off). I believe that's the case because the module object is a host object and doesn't quite support the ...
syntax yet.
To fix this specific case I just used Object.assign
instead (check react-native-netinfo/react-native-netinfo#717 for more details), but thinking from a compatibility perspective we should try to address this so that old/unmaintained libraries that use this pattern can benefit from the compatibility layer
Steps to reproduce
With bridgeless mode ON:
- Create a NativeModule
- Access the module on the JS side
- Export the module using the spread operator
Or just clone https://github.com/gabrieldonadel/rn-spread-operator-bug and run the app, it already includes all the use cases
React Native Version
0.74.0-rc.1
Affected Platforms
Runtime - Android, Runtime - iOS
Output of npx react-native info
System:
OS: macOS 14.0
CPU: (12) arm64 Apple M2 Max
Memory: 91.98 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.18.2
path: ~/.volta/tools/image/node/18.18.2/bin/node
Yarn:
version: 3.6.4
path: ~/.volta/tools/image/yarn/1.22.21/bin/yarn
npm:
version: 9.8.1
path: ~/.volta/tools/image/node/18.18.2/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.14.3
path: /Users/gabriel/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.2
- iOS 17.2
- macOS 14.2
- tvOS 17.2
- visionOS 1.0
- watchOS 10.2
Android SDK:
API Levels:
- "22"
- "26"
- "30"
- "31"
- "33"
- "34"
Build Tools:
- 26.0.3
- 30.0.3
- 31.0.0
- 33.0.0
- 33.0.1
- 33.0.2
- 34.0.0
System Images:
- android-22 | ARM 64 v8a
- android-26 | Google APIs Intel x86_64 Atom
- android-30 | ARM 64 v8a
- android-33 | Google APIs ARM 64 v8a
- android-33 | Google Play ARM 64 v8a
- android-34 | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2023.1 AI-231.9392.1.2311.11076708
Xcode:
version: 15.2/15C500b
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.8
path: /usr/bin/javac
Ruby:
version: 2.7.8
path: /Users/gabriel/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.74.0-rc.1
wanted: 0.74.0-rc.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
TypeError: _index.default.helloWorld is not a function (it is undefined), js engine: hermes
Reproducer
https://github.com/gabrieldonadel/rn-spread-operator-bug
Screenshots and Videos
bridgeless on | bridgeless off |
---|---|
Screen.Recording.2024-02-27.at.21.45.57.mov |
Screen.Recording.2024-02-27.at.21.44.31.mov |
Screen.Recording.2024-02-27.at.21.43.08.mov |
Screen.Recording.2024-02-27.at.21.41.17.mov |