Why React Native apps fail the privacy manifest check
Because the requirement is per-bundle, and your dependencies are someone else's bundles.
Apple's rule, from the privacy manifest documentation: "For each executable or dynamic library in an app that uses a required reason API, the bundle that includes the executable or dynamic library needs to include a privacy manifest file." A third-party SDK cannot rely on your app's manifest.
Since May 1, 2024, apps that don't describe their use of required reason APIs are not accepted by App Store Connect.
Hermes is on Apple's list, and it ships in nearly every RN app
Apple maintains a list of commonly used third-party SDKs that require both a privacy manifest and a signature. hermes is on it. So are a lot of things RN and Expo projects pull in routinely: the Firebase family, FBSDK, GoogleSignIn, GoogleUtilities, GTMSessionFetcher, OneSignal, SDWebImage, Lottie, Alamofire, AFNetworking, Kingfisher, OpenSSL, Protobuf, nanopb, RealmSwift, the RxSwift family, Reachability, SnapKit, Starscream, SwiftyJSON, leveldb, FMDB, Capacitor and Cordova.
Most React Native developers have never heard that Hermes is implicated. It is the default engine.
The gap Expo documents openly
Expo's Apple privacy guide states plainly that "Apple does not correctly parse all the PrivacyInfo files included by static CocoaPods dependencies," and its recommended remedy is to manually walk node_modules looking for PrivacyInfo.xcprivacy files and aggregate their values into your own manifest.
That is the actual state of the art: hand-auditing a dependency tree that routinely runs to hundreds of packages. Expo also flags its own guide as still in development.
What the manifest contains
The file must be named exactly PrivacyInfo.xcprivacy. Its four top-level keys, per Apple's documentation:
| Key | Type | Purpose |
|---|---|---|
NSPrivacyTracking | Boolean | Whether the app or SDK uses data for tracking |
NSPrivacyTrackingDomains | Array | Domains involved in tracking; required when tracking is true |
NSPrivacyCollectedDataTypes | Array | Data types collected, and why |
NSPrivacyAccessedAPITypes | Array | Required reason APIs used, each with declared reason codes |
Expo projects configure this through expo.ios.privacyManifests in app config rather than by hand-editing the plist.
The five required reason API categories
Per Expo's guide, the categories that require a declared reason are: UserDefaults, file timestamps, system boot time, disk space, and active keyboard.
Why a scan beats a checklist here
The problem is not that the rule is complicated — it is one sentence. The problem is that answering "does this project comply?" requires enumerating every executable and dynamic library in a dependency tree you did not write, and checking each against a list Apple updates. That is a machine's job. It is the job shipcheck was built to do.
shipcheck. "Why React Native apps fail the privacy manifest check." Baker Ventures LLC, September 4, 2026. https://shipcheck.bakerventuresstudio.com/rejections/react-native-privacy-manifest