npx testflight mirrors EAS Build and EAS Submit flows
Every prompt in npx testflight mirrors the EAS Build and EAS Submit flows, so you can answer the same way as when running eas build or eas submit separately. During the build and submission process, EAS dashboard links are generated so you can view the process, and after successful submission you receive a link to App Store Connect.
npx testflight workflow steps
The npx testflight command executes the following steps in order: Initialize or detect a linked EAS project; Confirm the bundle identifier and encryption type; Sign in to Apple Developer with two-factor authentication; Generate credentials (distribution certificate and provisioning profile); Create a production build to generate an iOS archive (.ipa) file; Verify App Store Connect access and create an API key if needed; Submit the app to TestFlight and enable internal testing group distribution.
Submissions dashboard access
You can find the submission details page at any time on the submissions dashboard for your project at https://expo.dev/accounts/[account]/projects/[project]/submissions, and it is linked from your build details page.
iOS TestFlight groups in submission profile
You can specify additional TestFlight groups using the groups field in your eas.json submission profile for iOS apps.
Android default submission behavior
By default, the --auto-submit flag will make your Android build available for internal testing. If sufficient metadata is not provided, the default behavior is to create an internal release for new apps. To control where and how your build is submitted, you can specify the releaseStatus and track fields in your eas.json submission profile.
iOS App Store review is manual
The release to Apple App Store review is a manual process. Once you have made a submission to TestFlight using --auto-submit, you must manually promote the build to the App Store. This behavior ensures that all iOS releases go through TestFlight when using --auto-submit, allowing you to test the release before deciding to make it available to the public.
Google Play Developer membership required for store upload
You can build and sign your app using EAS Build, but you cannot upload it to the Google Play Store unless you have a Google Play Developer membership, which requires a one-time $25 USD fee.
Apple Developer Program membership required for App Store builds
To create release builds for the Apple App Store using EAS Build, you need access to an account with a $99 USD Apple Developer Program membership.
App Store Review process overview
Review guidelines and rules are updated frequently, and enforcement of various rules can sometimes be inconsistent. There is no guarantee that your particular project will be accepted by either platform. You are ultimately responsible for your app's behavior. You can re-submit your app as needed to address feedback from reviews.
Privacy data collection for expo-updates
If you use expo-updates, when Apple asks privacy questions during submission, you will need to say 'Yes, we collect data from this app' and then select 'Crash Data'.
EAS Hosting environment variables are immutable per deployment
Environment variables are per deployment and deployments are immutable. After changing an environment variable, you must re-export the project and re-deploy for the changes to take effect.
EAS Hosting environment variable support
With EAS Hosting, only plain text and sensitive environment variables can be used. Secrets cannot be deployed with EAS Hosting. Client-side values are inlined in the JavaScript bundle when running npx expo export, while server-side values are stored on the server and deployed with API routes when running eas deploy.
EAS Submit Android-specific options
Android-specific options are available for EAS Submit configuration, including the track property for specifying the Google Play track (such as internal).
EAS Submit iOS-specific options
iOS-specific options are available for EAS Submit configuration, including appleId, ascAppId, and appleTeamId properties for Apple app store submission.
Example eas.json submit configuration for production
Example eas.json showing submit configuration with CLI version requirement (>= 0.34.0), production profile with android track set to internal, and iOS submission properties (appleId: john@turtle.com, ascAppId: 1234567890, appleTeamId: AB12XYZ34S).
Retry metadata push on partial failure
When the store config partially fails, you can change the store config and retry. The eas metadata:push command can be used to retry pushing the missing items.
Create store.config.json in project root
Create a store.config.json file in the root directory of your project. This file holds all the information you want to upload to the app stores. By default, EAS Metadata uses the store.config.json file at the root of your project, but you can change the name and location by setting the eas.json metadataPath property.
EAS Metadata requires Apple App Store app
EAS Metadata currently only supports the Apple App Store. You need an app registered with Apple to manage metadata for.
store.config.json basic structure example
A store.config.json file starts with a configVersion property and contains an apple object with localized info. The example shows: configVersion: 0, apple.info with en-US containing title, subtitle, description, keywords array, marketingUrl, supportUrl, and privacyPolicyUrl.
EAS Metadata supported platforms
EAS Metadata supports managing app store info programmatically, catching metadata issues before review, and collaborating on store presence updates. It does not support managing Google Play Store listings or uploading screenshots.
EAS Metadata with restricted app store accounts
EAS Metadata can be used with restricted app store accounts after authentication with the app store. Large corporate accounts with security restrictions may limit which EAS Metadata functionality is available due to permission constraints.
Using EAS Metadata with unsupported features
EAS Metadata only sends data from the store config to app stores and does not block you from using app store dashboards for unsupported features. When using both EAS Metadata and dashboard editing, run eas metadata:pull after dashboard changes to update your local store config and prevent overwriting those changes.
Apple review contact information fields
The apple.review object requires the following contact fields: firstName (string, min length 1), lastName (string, min length 1), email (string, must be valid email format), and phone (string, should be prefaced with '+' followed by country code, e.g., +44 844 209 0611). Optional fields include: demoUsername (string), demoPassword (string), demoRequired (boolean, indicates if sign-in is required to review app features), and notes (string, length 2-4000 for additional information to help during review).
Apple info minimal localized example
Minimal localized app store information requires at minimum the title (2-30 characters) and privacyPolicyUrl fields for each language code in the apple.info object. Example: {"en-US": {"title": "Awesome app", "privacyPolicyUrl": "https://example.com/en/privacy"}}
EAS Metadata copyright property
The apple.copyright property is a string field that contains the name of the person or entity that owns the exclusive rights to the app, preceded by the year the rights were obtained. Example format: '2008 Acme Inc.'
Apple advisory complete example with least restrictive answers
Complete advisory configuration with all content rating fields set to their least restrictive values uses NONE for all content type questions, false for gambling and unrestrictedWebAccess, null for kidsAgeBand, and NONE for both ageRatingOverride and koreaAgeRatingOverride.
Apple categories configuration examples
Categories can be configured as: an array with primary and secondary categories (example: ["FINANCE", "NEWS"]), or an array containing a nested array for primary category with subcategories plus a secondary category (example: [["GAMES", "GAMES_CARD", "GAMES_BOARD"], "ENTERTAINMENT"]).
Apple store categories list
Apple App Store categories include: BOOKS, BUSINESS, DEVELOPER_TOOLS, EDUCATION, ENTERTAINMENT, FINANCE, FOOD_AND_DRINK, GAMES (with up to 2 subcategories: GAMES_ACTION, GAMES_ADVENTURE, GAMES_BOARD, GAMES_CARD, GAMES_CASINO, GAMES_CASUAL, GAMES_FAMILY, GAMES_MUSIC, GAMES_PUZZLE, GAMES_RACING, GAMES_ROLE_PLAYING, GAMES_SIMULATION, GAMES_SPORTS, GAMES_STRATEGY, GAMES_TRIVIA, GAMES_WORD), GRAPHICS_AND_DESIGN, HEALTH_AND_FITNESS, LIFESTYLE, MAGAZINES_AND_NEWSPAPERS, MEDICAL, MUSIC, NAVIGATION, NEWS, PHOTO_AND_VIDEO, PRODUCTIVITY, REFERENCE, SHOPPING, SOCIAL_NETWORKING, SPORTS, STICKERS (with up to 2 subcategories: STICKERS_ANIMALS, STICKERS_ART, STICKERS_CELEBRATIONS, STICKERS_CELEBRITIES, STICKERS_CHARACTERS, STICKERS_EATING_AND_DRINKING, STICKERS_EMOJI_AND_EXPRESSIONS, STICKERS_FASHION, STICKERS_GAMING, STICKERS_KIDS_AND_FAMILY, STICKERS_MOVIES_AND_TV, STICKERS_MUSIC, STICKERS_PEOPLE, STICKERS_PLACES_AND_OBJECTS, STICKERS_SPORTS_AND_ACTIVITIES), TRAVEL, UTILITIES, and WEATHER.
Apple release automatic release date example
Automatic release can be scheduled using RFC 3339 format date. Example: {"automaticRelease": "2022-12-25T00:00:00+00:00"} schedules the app to be automatically released after store approval on December 25, 2022 at UTC midnight.
EAS Metadata version selection
The apple.version property specifies the app version to use when syncing all metadata defined in the store config. This is a string field. EAS Metadata selects the latest available version in the app stores by default if this property is not specified.
Apple info localized content fields
The apple.info object contains language-specific localized content with the following fields: title (string, length 2-30, required, reviewed before App Store availability), subtitle (string, max length 30, reviewed before App Store availability), description (string, length 10-4000), keywords (string array with unique items, max item length 100), releaseNotes (string, max length 4000), promoText (string, max length 170), marketingUrl (string, max length 255), supportUrl (string, max length 255), privacyPolicyText (string, for Apple TV), privacyPolicyUrl (string, max length 255, required for all apps), and privacyChoicesUrl (string, max length 255).
iOS app submission workflow structure
A submit workflow file contains: name (Submit iOS app), on section with push trigger for main branch, jobs section with two jobs: build_ios (type: build) and submit_ios (type: submit with needs: [build_ios]). The submit_ios job passes build_id from the build job output.
Android app setup requirements before production in Play Console
Before an Android app can go to production in Google Play Console, complete all remaining tasks on the Dashboard: privacy policy, store assets, and other details.
Google Play Console first release submission checklist
Steps to create the first Android release in Google Play Console: (1) Open Google Play Console and click Create app, (2) Enter App name, select Default language, App or game, Free or paid, and click Create app, (3) On the Dashboard, fill out app details and click View tasks under Start testing now, (4) On Internal testing page, create an email list of testers under Testers and click Save, (5) Click Create new release, (6) Select Google-generated key for signing, (7) Upload the .aab file under App bundles, (8) Enter Release name and click Next, (9) On Preview and confirm screen, click Save and publish, (10) Click Promote release to make the app available to testers or promote to production, (11) Share the testers link by clicking Testers > Copy link.
Android signing key options for Play Console
When creating a new release in Google Play Console, select 'Choose signing key' > 'Google-generated key'. Using a Google-generated key lets you upload your app even if you lose your Android keystore.
Android app bundle file format for Play Console
Upload an .aab (Android App Bundle) file to Google Play Console. If the build has not been created yet, create one with `eas build`.
Create Google Service Account key for EAS
EAS requires a Google Service Account key to submit apps on your behalf. Create the key following the guide at https://expo.fyi/creating-google-service-account. Upload it to EAS either via the EAS dashboard (Credentials > Android > Application identifier > Service Credentials > Add a Google Service Account Key) or via CLI with 'eas credentials --platform android' selecting production profile.
Android package name in app.json
Include the app's package name in app.json under the android section: {"android": {"package": "com.yourcompany.yourapp"}}
Submit Android app with eas submit command
Once a production build is ready, submit it to the Google Play Store with: eas submit --platform android. The command walks you through selecting a build and uploading it. Configure the submission process by adding a submission profile in eas.json.
Auto-submit build to Google Play
Pass --auto-submit to eas build to hand the finished build off to EAS Submit automatically: eas build --platform android --auto-submit
Archive and upload iOS build to App Store Connect
From the menu bar, open Product > Archive. Under Archives, click Distribute App from the right sidebar. Click App Store Connect and follow the prompts; Xcode will upload your build to App Store Connect. To get a .ipa file instead and upload it later, choose Export in the prompts and use Transporter. After uploading, sign in to App Store Connect, select your app, and submit it to TestFlight or for App Review from the App Store Connect dashboard.
Configure release scheme in Xcode
From the menu bar, open Product > Scheme > Edit Scheme. Select Run in the sidebar and set Build configuration to Release.
Open iOS workspace in Xcode for manual submission
From your project directory, run 'xed ios' to open the iOS workspace in Xcode. Then in the left sidebar select your app's workspace. Go to Signing & Capabilities and select All or Release. Under Signing > Team, choose your Apple Developer team; Xcode will generate an automatically managed provisioning profile and signing certificate.
Build iOS app for release
From the menu bar, open Product > Build. Xcode will build the release binary.
Manual iOS app submission workflow overview
This guide covers archiving an iOS app with Xcode and uploading it to App Store Connect. It is useful as a fallback when not using EAS Submit or when EAS Submit is temporarily unavailable. Most teams should use EAS Submit instead, which is simpler and works from any OS.
iOS submission prerequisites
To submit an iOS app to the Apple App Store you need: (1) a paid Apple Developer account (sign up at https://developer.apple.com/account/), (2) your app's bundle identifier included in app.json under ios.bundleIdentifier, (3) EAS CLI installed and authenticated with your Expo account via 'eas login'.
Submit iOS app with eas submit
Submit a production iOS app to the Apple App Store using the command 'eas submit --platform ios'. The command will guide you through selecting a build, prompt for your Apple ID on first run, and upload the binary to App Store Connect. The build appears in TestFlight after processing (usually 10-15 minutes). To release to production, log in to App Store Connect and submit the build for App Review.
Build and submit iOS app in one step
Pass the --auto-submit flag to eas build to hand the finished iOS build off to EAS Submit automatically. Use the command 'eas build --platform ios --auto-submit'. Refer to the Automate submissions documentation for additional details.
EAS Submit for iOS overview
EAS Submit is the recommended way to upload iOS apps to the Apple App Store. The eas submit command works consistently on your machine and inside CI/CD environments. EAS Workflows is the simplest way to run submissions automatically after a build. EAS Submit works on macOS, Linux, and Windows, so you don't need a Mac to ship iOS builds.
Quick start with single command for TestFlight
Use `npx testflight` (npm), `yarn dlx testflight` (yarn), `pnpm dlx testflight` (pnpm), or `bunx testflight` (bun) to create credentials, run a production build on EAS Build, and submit for internal testing via TestFlight in one command. Alternatively, use `eas build --platform ios --auto-submit` to build and submit in one step with the --auto-submit flag.
Submit existing build to TestFlight without rebuild
If you already have a production build, run `eas submit --platform ios` to submit it directly to TestFlight without rebuilding.
Paid Apple Developer account required for TestFlight
A paid Apple Developer account is required to submit apps to the Apple App Store and use TestFlight. Sign up on the Apple Developer Portal.
External testing requires internal group first
You must create an internal testing group before App Store Connect will allow you to create an external testing group.
Create internal testing group and add testers in App Store Connect
In App Store Connect, go to TestFlight, click the plus icon next to Internal Testing, enter the Internal Group name, and click Create. Then click the plus icon next to Testers to add testers from your App Store Connect team by selecting their emails and clicking Add. Testers receive an email invitation to test the app.
External testing requires beta app description and feedback email
External testing requires a beta app description and a feedback email before Apple accepts the build for Beta App Review. If your app has a login, you should enable Sign-in Information and provide a test account for Apple to use.
Local production build submission
To create a production build locally, see the local app production guide and then go through the app stores guide to submit your app.
npx testflight submission and testing setup
After the npx testflight command successfully submits to TestFlight, you receive a link to the App Store Connect dashboard where you can manage testers and distribution for your app's internal testing group.
--auto-submit flag for automatic submissions
The --auto-submit flag enables automatic submissions with EAS Build. When you run eas build --auto-submit, EAS Build passes the build along to EAS Submit with the appropriate submission profile upon completion. You are provided with a link to a submission details page where you can track the progress of the submission. The submission dashboard for your project is accessible at https://expo.dev/accounts/[account]/projects/[project]/submissions, and a link to it appears on your build details page.
Auto-submit submission profile selection
By default, --auto-submit uses a submission profile with the same name as the selected build profile. If this profile does not exist or you prefer to use a different one, use the --auto-submit-with-profile=<profile-name> flag instead.
Build profile environment variables during auto-submit
When running eas build --profile <profile-name> --auto-submit, the project's app.config.js is evaluated using any environment variables associated with the build profile <profile-name>. These variables are available during submission and affect the app configuration that gets submitted.