Skip to main content

Publishing Your App

This guide covers everything you need to build, submit, and update your app using Expo Application Services (EAS).

One-Time Setupโ€‹

Before your first build, link the project to your Expo account:

cd packages/rn
eas init

This adds a projectId to app.json. Commit this change โ€” it ties your project to your Expo account and is required for all EAS commands.

Prerequisitesโ€‹

npm install -g eas-cli

Required Tokens and Credentialsโ€‹

CredentialUsed ForWhere to Get It
Expo Access TokenAll EAS commands (build, submit, update)expo.dev โ†’ Account Settings โ†’ Access Tokens. Create a robot token for CI or a personal token for local use.
Apple IDiOS App Store submissionsYour Apple Developer account email. Must be enrolled in the Apple Developer Program ($99/year).
App-Specific PasswordiOS submissions via CIappleid.apple.com โ†’ Sign-In and Security โ†’ App-Specific Passwords. Required because EAS Submit can't do 2FA interactively.
Google Play Service Account JSONAndroid Play Store submissionsGoogle Cloud Console โ†’ Create a service account with "Service Account User" role โ†’ Download JSON key โ†’ Grant it access in Google Play Console under API Access. See EAS Submit Android docs.
App Store Connect App ID (ascAppId)iOS submissionsApp Store Connect โ†’ Your App โ†’ General โ†’ App Information. It's the numeric Apple ID.
Apple Team IDiOS buildsdeveloper.apple.com โ†’ Account โ†’ Membership โ†’ Team ID.

GitHub Actions Secretsโ€‹

If using the included CI workflows, add these as repository secrets (Settings โ†’ Secrets and variables โ†’ Actions):

  • EXPO_TOKEN โ€” required by all three workflows
  • EXPO_APPLE_ID โ€” required by EAS Submit (iOS)
  • EXPO_APPLE_APP_SPECIFIC_PASSWORD โ€” required by EAS Submit (iOS)

The Google Play service account JSON key should be placed at packages/rn/google-service-account.json (this path is gitignored).

CI Workflowsโ€‹

The repo includes three GitHub Actions workflows, all manual-only (workflow_dispatch) โ€” there are no automatic builds on push.

EAS Build (eas-build.yml)โ€‹

Runs lint and tests, then submits a cloud build to Expo. You choose the build profile (development, preview, or production) and platform (ios, android, or all). The --no-wait flag means CI exits after submitting the build job โ€” check build status on expo.dev.

EAS Submit (eas-submit.yml)โ€‹

Takes the latest successful EAS build and submits it to the App Store or Google Play Store.

EAS Update (eas-update.yml)โ€‹

Publishes an OTA (over-the-air) JavaScript bundle update. Users who already have the app installed receive the new JS code without downloading a new binary from the store.

Local Build and Submitโ€‹

You can build and submit directly from your machine:

cd packages/rn

# Login to Expo
eas login

# Build for both platforms
eas build --profile production --platform all

# Submit to iOS
eas submit --platform ios --profile production --latest

# Submit to Android
eas submit --platform android --profile production --latest

# OTA update (JS-only changes, no new binary needed)
eas update --branch production --message "your update message"

Build Profilesโ€‹

Three profiles are defined in eas.json:

ProfilePurposeDetails
developmentLocal developmentDebug build with dev client. iOS uses the simulator.
previewInternal testingInternal distribution build for testing on real devices before store submission.
productionStore releaseStore-ready build. Auto-increments version numbers.

Further Readingโ€‹

See SUBMIT.md in the repo for the full step-by-step App Store Connect and Google Play Console setup walkthrough.