Submit to App Stores
Build and submit iOS and Android apps using EAS
Submit to App Stores
EasyStarter's mobile app uses EAS (Expo Application Services) for cloud builds and app store submissions. EAS handles code signing, bundling, and automated submission — no local certificate setup required.
Before submitting, make sure the Server is deployed and RevenueCat and auth callbacks are correctly configured.
Prerequisites
| Platform | Required |
|---|---|
| iOS | Apple Developer account ($99/year), App created in App Store Connect |
| Android | Google Play Console account ($25 one-time), App created in Google Play |
| General | EAS CLI installed, logged into your Expo account |
npm install -g eas-cli
eas loginUpdate eas.json config
Before building, update the production profile's environment variables to point to your live URLs:
{
"build": {
"production": {
"autoIncrement": true,
"channel": "production",
"environment": "production",
"env": {
"EXPO_PUBLIC_SERVER_API_URL": "https://your-server.workers.dev", // Server production URL
"EXPO_PUBLIC_WEB_APP_URL": "https://your-app.com", // Web production URL
"EXPO_PUBLIC_REVENUECAT_IOS_API_KEY": "appl_xxxxxxxxxxxxxxxx",
"EXPO_PUBLIC_REVENUECAT_ANDROID_API_KEY": "goog_xxxxxxxxxxxxxxxx",
"EXPO_PUBLIC_REVENUECAT_ENTITLEMENT_ID": "pro"
}
}
}
}Update app.json identifiers
Confirm the bundle identifier and package name in apps/native/app.json match your app store accounts:
{
"expo": {
"name": "Your App Name",
"slug": "your-app-slug",
"version": "1.0.0",
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp", // Must match App Store Connect
"appleTeamId": "YOUR_TEAM_ID" // Found in your Apple Developer account
},
"android": {
"package": "com.yourcompany.yourapp" // Must match Google Play package name
},
"extra": {
"eas": {
"projectId": "your-eas-project-id" // Auto-generated by eas init
}
}
}
}If you haven't initialized the EAS project yet:
cd apps/native
eas initBuild the iOS production binary
pnpm -F native eas:build:ios:productionEquivalent to eas build --platform ios --profile production. EAS builds the .ipa file in the cloud.
On first build, EAS will guide you through:
- Creating or reusing an Apple Distribution Certificate
- Creating or reusing a Provisioning Profile
Check build status and download artifacts on the Expo Dashboard.
For a local build (requires macOS + Xcode), use
eas:build:ios:production:local.
Build the Android production binary
pnpm -F native eas:build:android:productionEquivalent to eas build --platform android --profile production. EAS builds an .aab file (Google Play's recommended format).
On first build, EAS will prompt you to upload or auto-generate an Android Keystore. Keep the Keystore safe — you must use the same Keystore to sign all future updates.
Submit to the App Store
pnpm -F native eas:submit:ios:productionEquivalent to eas submit --platform ios --profile production. EAS automatically uploads the build artifact to App Store Connect.
After upload:
- Sign in to App Store Connect
- Go to your App → TestFlight to verify the build
- Switch to the App Store tab and create a new version
- Fill in release notes, screenshots, keywords, and other metadata
- Submit for review (typically 1–3 business days)
Submit to Google Play
pnpm -F native eas:submit:android:productionEquivalent to eas submit --platform android --profile production.
After upload:
- Sign in to Google Play Console
- Go to your App → Release → Production
- Review the new build upload and fill in release notes
- Submit for review (typically a few hours to a few days)
OTA updates (no app store review required)
EasyStarter integrates Expo Updates, allowing you to push JavaScript-layer changes to installed apps without going through the app store review process.
Suitable for bug fixes, UI adjustments, and copy changes that don't touch native code:
# Push to the production channel
pnpm -F native eas:update:productionOTA updates can only update JavaScript/TypeScript code and static assets. They cannot update native modules (e.g. adding Expo plugins, modifying native fields in
app.json). Native changes still require a full build and store submission.
Version management
"autoIncrement": true in eas.json automatically increments the Build Number (iOS) and Version Code (Android) on every build — no manual changes to app.json needed.
| Field | Description |
|---|---|
version (in app.json) | User-visible version string, e.g. 1.2.0 — update manually |
| Build Number / Version Code | Internal store version — managed automatically by autoIncrement |
runtimeVersion | Controls OTA compatibility — defaults to appVersion policy |