iOS build fails: 'Orientation.hpp' file not found — Nitrogen header collision with react-native-unistyles
### How were you trying to build the app?
Production iOS build via EAS Build (Xcode 26, auto-assigned for Expo SDK 55), targeting TestFlight. Pod install completes. Xcode compilation phase fails inside the Pods build of `VisionCamera`.
```
node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Umbrella.hpp:302:10: fatal error: 'Orientation.hpp' file not found
302 | #include "Orientation.hpp"
| ^~~~~~~~~~~~~~~~~
node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp:304:10: fatal error: 'Orientation.hpp' file not found
```
Patching those two and re-running surfaces the next file with the same problem:
```
node_modules/react-native-vision-camera/nitrogen/generated/ios/c++/HybridCameraOutputSpecSwift.hpp:21:10: fatal error: 'Orientation.hpp' file not found
```
There are five sibling files in `nitrogen/generated/ios/c++/` that all do `#include "Orientation.hpp"` and all fail in turn:
- `HybridCameraOutputSpecSwift.hpp:21`
- `HybridDepthSpecSwift.hpp:36`
- `HybridFrameSpecSwift.hpp:29`
- `HybridOrientationManagerSpecSwift.hpp:21`
- `HybridPhotoSpecSwift.hpp:28`
Total of seven generated iOS headers need patching for the build to complete.
### Root cause
`react-native-unistyles` (3.2.3) also ships a Nitrogen-generated `Orientation.hpp`:
```
node_modules/react-native-vision-camera/nitrogen/generated/shared/c++/Orientation.hpp
node_modules/react-native-unistyles/nitrogen/generated/shared/c++/Orientation.hpp
```
Each library's podspec adds its own `nitrogen/generated/shared/c++` to `HEADER_SEARCH_PATHS`, and CocoaPods copies each via `CpHeader` into the framework Headers folder:
```
Unistyles.framework/Headers/Orientation.hpp
VisionCamera.framework/Headers/Orientation.hpp
```
The two `Orientation` enums are unrelated (one is screen orientation, ours is camera/frame orientation, in different namespaces), but the filenames collide.
VisionCamera's Nitrogen-generated bridge headers use quoted includes for own-module types:
```cpp
#include "Orientation.hpp"
```
With `useFrameworks: 'static'`, the search-path resolution becomes ambiguous: the include can land on the unistyles file, the wrong framework Headers folder, or fail outright depending on Pod build order and toolchain. Xcode 26 + Hermes-from-source surfaces it deterministically; older configurations sometimes hide it.
This is the same general class as the bluetooth-state-manager / multiple-image-picker issues from a few weeks back, where nitro 0.35 broke quoted include resolution from generated umbrella headers:
- patlux/react-native-bluetooth-state-manager#113
- NitrogenZLab/react-native-multiple-image-picker#260
The fix in those projects was the same shape — switch the broken quoted includes to angle-bracket framework form.
The structural fix belongs in nitrogen (filing separately at mrousavy/nitro), but vision-camera is the most-installed Nitro library so this report goes here too.
### Workaround (patch-package)
Seven one-line changes — `"Orientation.hpp"` → `<VisionCamera/Orientation.hpp>`:
```diff
diff --git a/node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp b/node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp
@@ -301,7 +301,7 @@
#include "MeteringMode.hpp"
#include "MirrorMode.hpp"
#include "NativeBuffer.hpp"
-#include "Orientation.hpp"
+#include <VisionCamera/Orientation.hpp>
#include "PhotoFile.hpp"
diff --git a/node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Umbrella.hpp b/node_modules/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Umbrella.hpp
@@ -299,7 +299,7 @@
#include "MirrorMode.hpp"
#include "NativeBuffer.hpp"
#include "ObjectOutputOptions.hpp"
-#include "Orientation.hpp"
+#include <VisionCamera/Orientation.hpp>
#include "OrientationSource.hpp"
```
Same change in the five `nitrogen/generated/ios/c++/Hybrid*Swift.hpp` files listed above. After patching, the iOS archive completes and uploads to TestFlight cleanly.
The `<NitroModules/...>` and `<NitroImage/...>` framework-form includes already in those same generated files prove the pattern works under the same build configuration.
### Suggested upstream fix
When Nitrogen emits iOS bridge files, prefer framework-form includes for any header that lives in another Nitro module's `nitrogen/generated/shared/c++/` — including the module's own:
```diff
-#include "Orientation.hpp"
+#include <VisionCamera/Orientation.hpp>
```
The module name is known at codegen time (it's in `nitro.json`). The substitution is mechanical and entirely backward-compatible — angle-bracket framework includes resolve via CocoaPods' modulemaps and cannot be ambiguous with another Pod's identically-named header.
### What I tried before patching
- Pinning `react-native-nitro-modules` to `0.35.4` exactly (no caret). No change.
- `eas build --clear-cache`. No change.
- `expo prebuild --clean`. No change.
- Toggling `useHermesV1`, `buildReactNativeFromSource`, `useFrameworks` between static and dynamic. Each combination either reproduces the collision or hides it temporarily depending on Pod build order — never a real fix.
- Removing the unistyles dependency makes the build pass, confirming the collision is the cause.
### Reproduction
Any project pairing these two libraries on iOS with `useFrameworks: 'static'`:
```
expo ~55.0.15
react-native 0.83.4
react-native-vision-camera 5.0.1
react-native-unistyles 3.2.3
react-native-nitro-modules 0.35.4
react-native-nitro-image 0.13.1
```
`app.config.js`:
```js
['expo-build-properties', {
ios: {
useFrameworks: 'static',
buildReactNativeFromSource: true,
useHermesV1: true,
},
}]
```
`eas build -p ios --profile production`.
### Project dependencies
```json
{
"react-native": "0.83.4",
"react-native-vision-camera": "^5.0.1",
"react-native-vision-camera-location": "^5.0.1",
"react-native-nitro-modules": "^0.35.4",
"react-native-nitro-image": "^0.13.1",
"react-native-unistyles": "^3.2.3",
"expo": "~55.0.15",
"expo-build-properties": "~55.0.13"
}
```
### VisionCamera Version
5.0.1
### Target platforms
iOS
### Operating system
MacOS (EAS Build worker)
### Can you build the VisionCamera Example app?
Not tested — the Example app does not include react-native-unistyles, so it would not reproduce.
### Additional information
- [x] I am using Expo
- [ ] I have enabled Frame Processors (react-native-worklets-core)
- [x] I have read the [Troubleshooting Guide](https://react-native-vision-camera.com/docs/guides/troubleshooting)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/mrousavy/react-native-vision-camera/blob/main/CODE_OF_CONDUCT.md)
- [x] I searched for [similar issues in this repository](https://github.com/mrousavy/react-native-vision-camera/issues) and found none — the closest is #3743 ("VisionCamera V5 fails to compile on Xcode 26 beta assigned by EAS Build for Expo SDK 54"), but that's a different surface error (`.o` rename failures, not an Orientation.hpp collision)
关闭于 2026-04-21 3 条评论