React Native iOS Apps
Overview
This guide covers building React Native iOS applications for Pie testing. The build must be self-contained with all JavaScript code bundled, so it can run without connecting to Metro bundler.
What You’ll Need
- React Native CLI: Version 0.60 or higher
- macOS Computer: iOS builds cannot be created on Windows or Linux
- Xcode: Latest version installed with command line tools
- Node.js: With npm or yarn installed
- CocoaPods: If your project uses native dependencies
Choose Your Build Method
React Native projects can be built using two methods:
- Manual Bundling: Full control over the bundling process (recommended for first-time builds)
- Automated Bundling: Faster process if your project is already configured
Manual Bundling Method
Step 1: Install Dependencies
Open terminal in your project root:
# Install JavaScript dependencies
npm install
# or
yarn install
# Install CocoaPods dependencies (if applicable)
cd ios && pod install && cd ..Step 2: Stop Metro Bundler
Ensure no Metro bundler is running to avoid conflicts:
# Kill any running Metro instances
killall -9 nodeAlternatively, close any terminal windows running Metro bundler.
Step 3: Bundle JavaScript Code
Run the bundle command from your project root:
npx react-native bundle \
--entry-file index.js \
--platform ios \
--dev false \
--bundle-output ios/main.jsbundle \
--assets-dest iosEntry file variations: Your project might use:
index.js— Standard JavaScript entryindex.tsx— TypeScript entryindex.ios.js— Platform-specific entry- Custom entry defined in
package.jsonorapp.json
This command creates:
- Production JavaScript bundle at
ios/main.jsbundle - Asset files (images, fonts) in the
iosfolder - Hermes bytecode files (
.hbc) if using Hermes engine - An assets folder (only if your project has images or fonts)
Step 4: Add Bundle to Xcode
Open your iOS project:
open ios/YourProjectName.xcworkspace(or
.xcodeprojif not using CocoaPods)In Project Navigator (left panel), right-click your project name
Select “Add Files to ‘[YourProjectName]’”
Navigate to the
iosdirectorySelect
main.jsbundleand the assets folder (if it exists)Important checkboxes:
- ✅ “Copy items if needed” must be checked
- ✅ Your app target must be selected under “Add to targets”
Click “Add”
Verify: Click main.jsbundle in Project Navigator and check the File Inspector (right panel) to confirm your target is checked under “Target Membership”.
Step 5: Configure JavaScript Loading
Update your AppDelegate to load the bundled JavaScript instead of Metro.
For Objective-C (AppDelegate.m)
Find the jsCodeLocation configuration in the application:didFinishLaunchingWithOptions: method.
Replace the existing code with:
jsCodeLocation = [[NSBundle mainBundle]
URLForResource:@"main"
withExtension:@"jsbundle"];If you see conditional DEBUG code like this, the Release build already uses the bundle:
#if DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings]
jsBundleURLForBundleRoot:@"index"];
#else
jsCodeLocation = [[NSBundle mainBundle]
URLForResource:@"main"
withExtension:@"jsbundle"];
#endifFor Swift (AppDelegate.swift)
Replace the existing code with:
let jsCodeLocation = Bundle.main.url(forResource: "main",
withExtension: "jsbundle")If conditional DEBUG code is present, the Release build already uses the bundle:
#if DEBUG
let jsCodeLocation = RCTBundleURLProvider.sharedSettings()
.jsBundleURL(forBundleRoot: "index")
#else
let jsCodeLocation = Bundle.main.url(forResource: "main",
withExtension: "jsbundle")
#endifStep 6: Build the App
Select your target simulator in Xcode (latest iOS version recommended)
Choose your build scheme:
- Debug — Larger file size, includes diagnostics
- Release — Optimized build (recommended for testing)
Navigate to Product → Clean Build Folder (⇧⌘K)
Navigate to Product → Build (⌘B)
Wait for the build to complete successfully
Step 7: Test Your Build Offline
This is a critical verification step:
- Disable network connectivity (turn off WiFi)
- Close all terminal windows (ensure Metro isn’t running)
- Open iOS Simulator
- Navigate to Product → Show Build Folder in Finder
- Go to:
- Debug:
Build/Products/Debug-iphonesimulator/ - Release:
Build/Products/Release-iphonesimulator/
- Debug:
- Drag the
.appfile into the simulator to install it - Launch the app and verify it starts without errors
- Test core functionality to confirm everything works
- Re-enable network
Step 8: Package for Upload
- Right-click the
.appfile in Finder - Select “Compress” to create a
.ziparchive - Upload to Pie’s upload portal
Step 9: Restore Development Settings (Optional)
If you modified AppDelegate.m or AppDelegate.swift, restore the original code to continue local development with Metro bundler.
Automated Bundling Method
If your project has the “Bundle React Native code and images” build phase configured:
Quick Steps
Open your project:
open ios/YourProjectName.xcworkspaceSelect your app target → Build Settings
Search for “Build Configuration” and set it to “Release”
Navigate to Product → Clean Build Folder (⇧⌘K)
Navigate to Product → Build (⌘B)
The JavaScript bundle is created automatically during build
Locate your
.appfile in Product → Show Build Folder in FinderTest offline, compress to
.zip, and upload
Troubleshooting
Blank or White Screen
Possible Causes:
- Bundle not found in app bundle
- Incorrect entry file specified
- Hermes compatibility issues
Solutions:
- Verify
main.jsbundlehas Target Membership checked in Xcode - Confirm entry file name (check
package.jsonfor custom entry) - If using Hermes, ensure all dependencies are compatible
App Tries to Connect to Metro (localhost:8081)
Possible Causes:
- AppDelegate still in development mode
- Debug scheme selected instead of Release
- Cached build artifacts
Solutions:
- Verify AppDelegate changes were saved
- Switch to Release scheme or update AppDelegate code
- Clean Build Folder and rebuild: Product → Clean Build Folder
- Search codebase for hardcoded
localhost:8081references
Assets Not Loading (Missing Images/Fonts)
Possible Causes:
- Assets folder not added to Xcode
- Assets not included in target
- Incorrect asset paths in code
Solutions:
- Verify assets folder was added with “Copy items if needed”
- Check Target Membership in File Inspector
- Confirm code uses correct relative paths for assets
Native Modules Failing
Possible Causes:
- CocoaPods not installed
- Static linking issues
- New architecture compatibility (RN 0.68+)
Solutions:
- Run
cd ios && pod install && cd .. - Check module documentation for static build requirements
- Verify module compatibility with React Native architecture
Build Errors in Xcode
Possible Causes:
- Hermes configuration issues
- Missing bundle file
- Duplicate symbols
Solutions:
- Verify
hermes_enabledinios/Podfile - Confirm
ios/main.jsbundleexists - Delete DerivedData:
rm -rf ~/Library/Developer/Xcode/DerivedData
Hermes Engine Considerations
If your project uses Hermes (default in React Native 0.70+):
- ✅ Bundling process remains the same
- ✅ Generates more efficient bundles with better performance
- ✅ Smaller file sizes
- ✅ Check
ios/Podfileforhermes_enabled = true - ⚠️ Ensure all dependencies are Hermes-compatible
Build Scheme Comparison
| Feature | Release | Debug |
|---|---|---|
| Bundle Size | Smaller | Larger |
| Performance | Optimized | Unoptimized |
| Debug Symbols | No | Yes |
| Recommended For | Pie Testing | Issue Diagnosis |
Recommendation: Use Release builds for Pie testing as they represent production-like behavior.
Additional Resources
- React Native Publishing Guide
- React Native version-specific release notes
Next Steps
- Upload your build to Pie’s upload portal
- Review Post-Upload Requirements
- Pie’s AI agents will begin testing within 30 minutes
Need Help?
Contact Pie Labs support with:
- React Native version
- Build errors or console logs
- Screenshots of relevant issues
- Description of what you’ve tried