iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

App Store / Play Store

Publishing a React Native app to the App Store and Play Store. The pipeline: bump versions, build a signed binary, upload via EAS Submit (or fastlane), fill in store listings, attach screenshots, and submit. After review, deploy JS-only updates via EAS Update without rebuilding.

EAS Submit, store listings, screenshots, rollouts

EXAMPLE
# ===== Prereqs =====
# - Apple Developer account + App Store Connect access
# - Google Play Console account
# - EAS CLI:           npm i -g eas-cli
# - Logged in:         eas login
# - Configured:        eas init  (creates eas.json)

# ===== 1) eas.json — the build matrix =====
{
  "cli": { "version": ">= 10.0.0" },
  "build": {
    "development": { "developmentClient": true, "distribution": "internal" },
    "preview":     { "distribution": "internal", "ios": { "simulator": true } },
    "production":  { "autoIncrement": true, "env": { "API_BASE": "https://api.example.com" } }
  },
  "submit": {
    "production": {
      "ios":     { "ascAppId": "6471234567", "appleId": "you@example.com", "ascApiKeyPath": "./asc-api.json" },
      "android": { "track": "internal", "serviceAccountKeyPath": "./play-service-account.json" }
    }
  }
}

# ===== 2) Bump version + build =====
# app.json / app.config.ts
# {
#   expo: {
#     version: '1.4.0',
#     ios:     { buildNumber: '142' },
#     android: { versionCode: 142 },
#     runtimeVersion: { policy: 'appVersion' },
#     updates: { url: 'https://u.expo.dev/<project-id>' }
#   }
# }

eas build --platform all --profile production

# Output: signed .ipa + .aab on EAS infrastructure. Download URLs to test
# from a real device before submitting.

# ===== 3) Submit =====
eas submit --platform ios     --latest --profile production
eas submit --platform android --latest --profile production

# Manual alternative: download artefacts from EAS, upload via:
# - iOS:     Transporter app or 'xcrun altool --upload-app'
# - Android: Google Play Console -> Internal testing -> Create release

# ===== 4) App Store Connect — checklist =====
# - App information: subtitle (30 char), keywords (100 char), support URL
# - Pricing + availability
# - App privacy: data types collected, link to privacy policy
# - Age rating questionnaire
# - Build selection (choose the EAS-uploaded one)
# - What's new in this version
# - Promotional text (up to 170 char, changeable without re-review)
# - Screenshots:
#   6.7" / 6.5" iPhone (mandatory)
#   13" iPad if you support iPad
#   1290x2796 / 1242x2688 / 2064x2752
# - App Preview videos (optional but helpful)
# - Demo account credentials (required if gated content)

# ===== 5) Google Play Console — checklist =====
# - App access (any login-gated features need a test account)
# - Ads declaration
# - Content rating questionnaire (IARC)
# - Target audience + content
# - News app? Government app? Health app? Disclose accordingly
# - Data safety form (analogous to App Privacy on iOS)
# - Store listing: short description (80), full description (4000)
# - Graphic assets: icon 512x512, feature graphic 1024x500
# - Screenshots: phone (1080p), 7" tablet, 10" tablet
# - Promo video (YouTube URL)
# - Countries to release in

# ===== 6) Staged rollout =====
# Play Console -> Production -> 5% -> 25% -> 50% -> 100% over a week.
# Stop if crash rate ticks up or rating drops.
#
# App Store Connect -> Phased Release for Automatic Updates (7-day curve).

# ===== 7) Once approved: ship JS-only updates via EAS Update =====
eas update --branch production --message 'Fix checkout copy'
# Devices fetch on next launch. Stay within the runtimeVersion bound or the
# bundle is rejected.

# ===== 8) After-launch ops =====
# - Crashlytics + Sentry alerts wired to Slack
# - Reviews monitor: tools like AppFollow / a daily cron emailing top 1-stars
# - Subscription metrics (RevenueCat / Adapty) if you sell IAPs
# - Watch retention curves; rage uninstalls show up in 'Last 7 days' Play data

# ===== 9) Common rejections + fixes =====
# - 'Missing demo account' (iOS)              -> provide one in App Review notes
# - 'Privacy policy URL required'              -> add to App Store + Play Console
# - 'Background mode misuse' (iOS)             -> remove unused entitlement
# - 'Target API level too old' (Play)          -> bump targetSdkVersion
# - 'Crash on launch on review device'         -> test on a CLEAN device before submission
# - 'Misleading IAP descriptions'              -> match the in-app copy exactly
# - 'Permissions justification' (Play)         -> short reason for each permission

# ===== 10) Pitfalls =====
# - Submitting on a Friday — review queues are longer over weekends
# - Skipping staged rollout — a regression hits everyone at once
# - OTA pushing JS that calls native APIs the binary does not have
#   (mismatched runtimeVersion = crash storm)
# - Forgetting to keep the signing keystore safe — losing it bricks future updates
# - Not having a rollback plan — keep the previous build .aab to revert quickly

Why it matters

Always do a staged rollout on Play (5% → 25% → 100%) and use Phased Release on App Store. If Crashlytics ticks up at 5%, you pause; if it stays flat, you continue. The cost is one or two weeks of slower distribution; the benefit is never "we shipped to 100M users on Tuesday and 30% had a crash on launch".

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Build and submit
eas build -p ios --profile production
eas submit -p ios --latest
eas build -p android --profile production
eas submit -p android --latest
Try it Yourself »

Discussion

Loading…