After upgrading to React Native 0.87 (or Expo SDK 58), some iOS builds stop inside a library:
node_modules/react-native-date-picker/ios/DatePicker.m:7:9: error: 'RCTComponent.h' file not found
node_modules/@react-native-menu/menu/ios/MenuViewManager.mm:3:9: 'RCTBridge.h' file not found
The release notes explain why in one line: React Native 0.87 ships its iOS headers as header-only XCFrameworks, and "if you import a React Native header without its namespace, add it". So #import <RCTAppDelegate.h> becomes #import <React/RCTAppDelegate.h>.
That leaves questions the notes don't answer. Does the quoted form #import "RCTBridge.h" break too? Every header, or some? What about apps that build React Native from source? I wanted NativeKeel to warn about this before an upgrade, so I needed exact answers, not a regex that cries wolf.
The experiment
I created a React Native 0.87.1 app (Xcode 26.2) and generated one source file per header: all 227 RCT*.h headers under react-native/React, each imported on its own, once as "RCTX.h" and once as <RCTX.h>. Then I compiled them twice: with the default prebuilt React Native core, and with RCT_USE_PREBUILT_RNCORE=0 (built from source).
| Import | Default (prebuilt) | Built from source |
|---|---|---|
#import <React/RCTBridge.h> |
works | works |
#import "RCTBridge.h" |
file not found | works |
#import <RCTBridge.h> |
file not found | file not found |
The exceptions are small but matter: in quotes, RCTFabricComponentsPlugins.h, RCTComponentViewHelpers.h, the CoreModules headers and RCTLocalizedString.h still resolve. That's why most Fabric libraries, which write #import "RCTFabricComponentsPlugins.h", build fine.
One more pattern is safe: an import inside an #if __has_include(<React/RCTBridge.h>) … #else #import "RCTBridge.h" fallback. The compiler takes the first branch, and many older libraries are written exactly like that.
Which libraries hit it
With those rules, I scanned the iOS sources of the 248 most downloaded React Native libraries with native iOS code (16 October 2026). Five fail:
| Library | Import | Status |
|---|---|---|
| react-native-date-picker 5.0.13 |
"RCTComponent.h", "RCTConvert.h"
|
issue open |
| @react-native-menu/menu 2.0.0 | "RCTBridge.h" |
fix proposed in a PR |
| react-native-bottom-tabs 1.4.0 | "RCTConversions.h" |
fixed on main, next release |
| react-native-ios-context-menu 3.2.1 | "RCTBridge.h" |
fix proposed in a PR |
| react-native-ios-utilities 5.2.0 | "RCTBridge.h" |
no report yet |
Three of them already have "file not found" reports from people who upgraded, which is a good sign the rules match reality. In the 1,040 open-source apps I test with, 31 depend on at least one of these five.
What to do
- Update the library if a release has the change.
- Otherwise patch the import and keep it with patch-package:
- #import "RCTComponent.h"
+ #import <React/RCTComponent.h>
-
Temporary workaround: build React Native from source, where the quoted form still resolves:
RCT_USE_PREBUILT_RNCORE=0 bundle exec pod install, orbuildReactNativeFromSource: trueunderiosinexpo-build-properties. Clean builds get much slower, and it doesn't help with<RCTBridge.h>.
Check your own AppDelegate and native modules too: the same rule applies to app code.
Finding it before the upgrade
NativeKeel now reads the iOS code of your installed libraries and your own ios/ folder. On React Native below 0.87 it lists these imports as work for the upgrade; on 0.87 and later it reports them as the reason the build fails, with file and line:
npx nativekeel
The full table, with links to each issue and PR: nativekeel.com/fix/rctcomponent-h-file-not-found-react-native-0-87.
If a library you use fails this way and isn't in the table, tell me and I'll add it.
Top comments (0)