Guides
The pre-submission checks worth running are the ones where the message names a guideline but not a file. Those are deterministic, they live in the repository, and a machine can find them before you build.
The six-minute pre-submission pass
# 1. Which dependencies already ship a privacy manifest?
find node_modules -name "PrivacyInfo.xcprivacy" | sed 's|node_modules/||' | cut -d/ -f1 | sort -u
# 2. Every manifest in the tree parses?
find . -name "PrivacyInfo.xcprivacy" -exec plutil -lint {} \;
# 3. What permissions and background modes do you actually ship?
/usr/libexec/PlistBuddy -c "Print" ios/*/Info.plist | grep -i 'UsageDescription' -A1
/usr/libexec/PlistBuddy -c "Print :UIBackgroundModes" ios/*/Info.plist 2>/dev/null
# 4. What did your libraries add to the Android manifest?
find android -path '*intermediates*' -name 'AndroidManifest.xml' | head -1 \
| xargs grep -E 'uses-permission|foregroundServiceType'
# 5. Does anything in your metadata name another mobile platform?
grep -rniE 'android|google play|play store' fastlane/metadata/ store/ 2>/dev/nullThen answer one question per finding: which user-facing feature stops working if this is removed? Anything you cannot answer is a rejection waiting, because App Review will ask the same question and you will not have a better answer then.
The one that catches Expo teams
With continuous native generation, ios/ and android/ are build artefacts, regenerated on every prebuild. A fix applied there works locally, vanishes on the build server, and produces an identical second rejection — two cycles, several days, and the change was correct both times.
Anything that must survive a build has to live in app.json, app.config.js or a config plugin. Why RN and Expo fail differently.
shipcheck. “Guides.” Baker Ventures LLC, September 6, 2026. https://shipcheck.bakerventuresstudio.com/guides/