iOS Basics for RN Devs
Xcode essentials without becoming an iOS engineer full-time - the minimum mental model React Native developers need when npx expo run:ios, EAS Build, or a native crash log pulls you into Apple's toolchain on SDK 57.
Search across all documentation pages
Xcode essentials without becoming an iOS engineer full-time - the minimum mental model React Native developers need when npx expo run:ios, EAS Build, or a native crash log pulls you into Apple's toolchain on SDK 57.
Quick-reference recipe card - copy-paste ready.
# Generate ios/ from app.config.ts (CNG) and run on simulator
npx expo prebuild --platform ios
npx expo run:ios
# Pick a specific simulator
npx expo run:ios --simulator "iPhone 16 Pro"
# USB device (requires Apple Developer account + Xcode)
npx expo run:ios --device
# Open the workspace when you must inspect native build settings
open ios/*.xcworkspace
# List simulators and connected devices
xcrun simctl list devices available
xcrun xctrace list devicesWhen to reach for this:
ios/ after npx expo prebuild.app.config.ts, not pbxproj.Step 1 - Understand what prebuild generated
ios/
├── Podfile ← CocoaPods dependency manifest (autolinking writes here)
├── Podfile.lock ← Pinned pod versions (commit if ios/ is in git)
├── YourApp.xcworkspace ← OPEN THIS in Xcode (includes Pods project)
├── YourApp.xcodeproj ← App target only - wrong entry when Pods exist
└── YourApp/
├── AppDelegate.swift ← RN entry; rarely hand-edit under CNG
├── Info.plist ← Permissions strings; prefer app.config plugins
└── YourApp.entitlements ← Push, associated domains, app groupsStep 2 - Run from CLI (daily path)
npx expo install expo-dev-client
npx expo prebuild --platform ios
npx expo run:ios --simulator "iPhone 16 Pro"
npx expo start --dev-clientStep 3 - Open Xcode only when needed
open ios/ShopApp.xcworkspaceIn Xcode:
ShopApp → selects the app target to build.⌘R): same as npx expo run:ios but with GUI breakpoints in native code.app.config.ts.Step 4 - Read a native build failure
▸ Compiling SomePod.m
❌ 'SomeHeader.h' file not foundTypical RN/Expo fix order:
cd ios && pod install && cd ..
npx expo prebuild --platform ios --no-clean # only if ios/ is committed
npx expo run:iosIf the error is signing:
error: No profiles for 'com.example.app' were foundFix in EAS iOS credentials or Xcode → Signing → select your Team - not by disabling signing.
What this demonstrates:
.xcworkspace.app.config.ts plugins.| Xcode term | RN / Expo equivalent |
|---|---|
| Target | The .app binary (your app, or a widget extension) |
| Scheme | Build + run configuration for a target (Debug/Release) |
| Workspace | App project + Pods.xcodeproj |
| Bundle Identifier | ios.bundleIdentifier in app.config.ts |
| Provisioning Profile | Apple-signed permission slip tying cert + bundle ID + devices |
| Capabilities / Entitlements | ios.associatedDomains, push, keychain - see Entitlements & Capabilities |
| Info.plist | Permission usage strings, URL schemes, background modes |
| Archive | Release build for TestFlight - eas build does this in CI |
| Debug | Release | |
|---|---|---|
| Hermes | Dev tools enabled | Optimized bytecode |
| JS bundle | Metro dev server | Embedded production bundle |
| Signing | Development cert | Distribution cert |
| Use when | Daily dev, USB debugging | TestFlight, App Store |
npx expo run:ios builds Debug by default. Store binaries come from eas build --profile production.
# Boot a simulator without running the app
xcrun simctl boot "iPhone 16 Pro"
# Open a URL (universal link smoke test)
xcrun simctl openurl booted "https://shop.example.com/orders/42"
# Erase state (stuck keychain / cached AASA)
xcrun simctl erase bootedios/| Model | You edit | Xcode role |
|---|---|---|
CNG (gitignored ios/) | app.config.ts, plugins | Debugger only; regenerated on prebuild |
| Committed native | ios/ + plugins | Merge native changes carefully on SDK bumps |
SDK 57 default: npx expo prebuild runs --clean - see Prebuild Basics.
AppDelegate or a third-party SDK.For JS debugging, prefer React Native DevTools and Metro - not Xcode breakpoints in application code.
.xcodeproj instead of .xcworkspace - Pods headers missing, build fails. Fix: always open ios/*.xcworkspace.Info.plist / entitlements by hand under CNG - wiped on next prebuild. Fix: config plugin or app.config.ts ios fields.app.config.ts, Apple Developer portal, and AASA appID must match exactly.ios/ is generated, delete and prebuild --clean before deep manual merges.| Alternative | Use When | Don't Use When |
|---|---|---|
eas build --local | Reproduce cloud iOS build on your Mac | You only need a quick simulator Debug run |
| Xcode Cloud | Team already on Apple CI | Standard Expo teams - EAS Build is simpler |
npx react-native run-ios | Bare RN without Expo prebuild | Expo projects - loses config plugin pipeline |
| VS Code + sweetpad | Lighter editor integration | Complex signing issues - use Xcode GUI |
expo.ios.deploymentTarget in app.config.ts, or expo-build-properties plugin.npx expo start --dev-client --tunnel or USB with appropriate hostname flags.npx react-native log-ios or xcrun simctl spawn booted log stream --predicate 'processImagePath contains "YourApp"'.rm -rf ~/Library/Developer/Xcode/DerivedData.cd ios && pod install && cd .. and rebuild.app.config.ts, not ios/.ios/ including Podfile.lock - see CocoaPods & Pod Install.pod install and Apple Silicon quirksStack versions: This page was written for React 19.2.3, React Native 0.86.0, and Expo SDK 57 (
expo~57.0.4).
Reviewed by Chris St. John·Last updated Jul 16, 2026