React Native tutorial
Publish a React Native app: native build and store checklist
This guide prepares a bare React Native CLI project for App Store and Google Play submission through Shiptavio. It covers native identity, CocoaPods, release builds, source packaging, and the failures that most often block a store upload.
By Shiptavio · Updated 26 October 2026 · 10 min read · React Native CLI
1. Confirm the app is a fit
Shiptavio publishes free apps under the Apple Developer and Google Play organization accounts of our Malaysia-based organization. Check the commercial and category limits before you start.
- The app is free. No paid download, in-app purchase, or digital subscription.
- The app is not in a prohibited category.
- Every API uses production HTTPS.
- You own the code, name, logo, and content.
- You can provide a demo account if the app has a login.
2. Set the app identity and versions
A React Native CLI project keeps identity in several native files. Set them before the first build and keep them stable.
- iOS: set the bundle identifier and version in the Xcode target, and confirm CFBundleShortVersionString and CFBundleVersion.
- Android: set applicationId, versionName, and versionCode in android/app/build.gradle or build.gradle.kts.
- App name: check app.json, the iOS display name, and the Android app label.
- Increment the build number and versionCode for every store upload.
// android/app/build.gradle.kts
defaultConfig {
applicationId = "com.yourcompany.myapp"
versionCode = 42
versionName = "1.2.0"
}3. Install native dependencies
The iOS build depends on CocoaPods. A stale Podfile.lock is a common reason a project builds on one machine and fails on another.
- Commit package.json and the lockfile.
- Commit ios/Podfile.lock. Do not send ios/Pods/.
- Keep android/gradle.properties and the Gradle wrapper in the source.
- If a library needs a native setup step, document it in the build notes.
npm ci
cd ios && pod installnpx react-native doctor4. Handle environment values safely
React Native build-time configuration can end up inside the app bundle. Treat anything compiled into the app as public.
- Use production HTTPS URLs for API endpoints.
- Do not put private API keys, signing secrets, or service-role keys in the app.
- Add non-secret values in the Shiptavio submission form or through the CLI --env-file option.
- If you use react-native-config or a similar package, document which file the build expects.
5. Run the release builds
Shiptavio runs the native release build on its Mac. A local build catches missing native modules before you send the source.
- Replace MyApp and the workspace name with your project's names.
- Use the same Hermes and New Architecture settings that you tested.
- Check the Android minSdkVersion, compileSdkVersion, and targetSdkVersion required by your libraries.
- Do not send the ios/build/ or android/app/build/ output.
xcodebuild -workspace ios/MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-destination "generic/platform=iOS" \
archivecd android
./gradlew bundleReleaseIf your project has a custom build script, add the exact command to the build command field. We build from your source, not from a guessed command.
6. Package the source
Send the native project, not a binary. The ios/ and android/ folders are part of the source.
- Include ios/, android/, package.json, the lockfile, and source files.
- Leave out node_modules, ios/Pods/, android/.gradle/, build output, .env files, keystores, and private keys.
- Add the Shiptavio account as a read-only collaborator if the repository is private.
- The source limit is 200 MB.
git add ios android package.json yarn.lock
git commit -m "Prepare React Native release"
git archive --format=zip -o my-app-source.zip HEAD7. Submit to Shiptavio
Create the app record, choose React Native CLI, and add the source and store details.
- Add the exact build command and any custom native setup.
- Add non-secret production environment values.
- Include icons, screenshots, store text, privacy policy, and a demo account if needed.
- Tell us in the build notes if the app uses an OTA service.
8. Updates and common failures
A store update uses one release credit. OTA services are separate and require their own credentials.
- Pod install failure: run pod repo update, then pod install. Delete ios/Pods only if the install is still broken, then run pod install again. Keep the lockfile unless you intend to update dependencies.
- Duplicate build number: increment the iOS build number and Android versionCode.
- Missing native module: run a clean install and rebuild, then send the error if it persists.
- Hermes or New Architecture mismatch: document the setting in the build notes.
- CodePush or another OTA service: tell us before submission. Shiptavio does not manage it.
- Do not change the bundle identifier or package name between updates.
Common questions
Do I need a Mac to build a React Native app?
Should I send ios/Pods/?
Can I use an OTA service like CodePush?
Can I send an existing IPA or AAB?
Can I use a custom Gradle or NDK version?
What happens if the native build fails?
Related guides
Publish a React Native app
The service overview, scope, and pricing.
Expo publishing tutorial
For React Native projects that use Expo.
Flutter publishing tutorial
For apps built in Dart with Flutter.
How to submit
The dashboard flow from account creation to store review.
Compare publishing options
Shiptavio, Expo EAS, Codemagic, and Fastlane.
Ready to send the project?
Register the app and add the source. A person reviews the project before the build starts.