Building & Releasing
Writing and testing your app is most of the work, but getting it into a real user's hands is its own process with its own vocabulary — signing, bundles, store submission, versioning. The exact steps differ depending on whether your project is Expo-managed or a bare React Native CLI project, so this page covers both paths.
Expo-Managed Projects: EAS Build
For Expo-managed projects, EAS Build (Expo Application Services) is the modern, cloud-based way to produce a release build. Instead of needing your own Mac for iOS builds or a fully configured Android Studio setup locally, EAS Build compiles your app on Expo's own build servers and hands you back an installable file.
// Build a release for each platform via Expo's cloud build service
eas build --platform android
eas build --platform ios
EAS Build handles a lot of the fiddly setup automatically — generating and managing signing credentials, running the native compile step, and producing the final installable artifact — which is why it's become the default recommendation for most Expo projects today.
Bare React Native CLI Projects: Building Directly
Without Expo's managed build service, you build using each platform's own native tooling directly.
On Android, that means running Gradle's release task from the project's android
folder; on iOS, it means opening the project in Xcode and using its Archive workflow.
// Conceptual: build a release APK/AAB directly with Gradle (Android)
cd android
./gradlew assembleRelease
iOS release builds for a bare project are done through Xcode itself (Product → Archive), since Apple's toolchain doesn't offer an equivalent simple one-line command the way Gradle does for Android.
Android App Signing: A Critical Warning
Every Android release build must be cryptographically signed with a keystore — a file containing your app's signing key. The Play Store uses this signature to verify that every update to your app genuinely comes from you, the original publisher.
Android App Bundle (.aab)
The Play Store requires new apps to be submitted as an Android App Bundle
(a .aab file) rather than a plain .apk. An app bundle contains all your
app's compiled code and resources, and Google Play itself generates and serves optimized,
device-specific APKs from it — so a user with a lower-resolution phone doesn't download assets
meant for a much larger screen.
iOS Builds: Mac, Xcode, and an Apple Developer Account
Unlike Android, building for iOS genuinely requires a Mac running Xcode — there is no cross-platform way around this requirement, Expo's cloud builds included, since Apple's toolchain only runs on macOS. You'll also need a paid Apple Developer account to sign and submit a build. Submission itself happens through App Store Connect, Apple's web portal for managing your app's listing, builds, and review status.
EAS Submit: Automating Store Submission
For Expo projects, EAS Submit automates the actual upload-to-the-store step as well, taking a build produced by EAS Build and pushing it directly to the Play Store or App Store Connect without you manually uploading files through each store's own console.
eas submit --platform android
eas submit --platform ios
Versioning Your App
Every release needs two distinct version identifiers: a user-facing version string
(like 1.2.0) that appears in the store listing, and a platform-specific
build number that must strictly increase with every single submission, even ones
that only bump a patch version.
// app.json (Expo-managed project)
{
"expo": {
"version": "1.2.0",
"ios": { "buildNumber": "14" },
"android": { "versionCode": 14 }
}
}
In a bare React Native CLI project, the same idea is split across package.json's
version field (mostly informational) and the native project files themselves —
android/app/build.gradle's versionCode/versionName for
Android, and the target's version/build settings inside the Xcode project for iOS. Whichever
approach you use, forgetting to bump the build number is one of the most common reasons a store
submission gets rejected outright.
Over-the-Air (OTA) Updates with expo-updates
One genuinely distinctive React Native/Expo capability is pushing a JavaScript-only bug fix to
users' devices without going through app store review again. The
expo-updates library checks for a new JS bundle when the app starts, downloads it in
the background, and applies it — so a typo fix or a small logic bug can reach every user within
minutes instead of the days a full store review can take.