DEV Community

Lucas Martin
Lucas Martin

Posted on

EAS Submit in 2026: What It Automates, What It Doesn't, and the Release Pipeline That Covers Both

eas submit is one of the best things in the Expo toolchain. One command takes a production build and uploads it to App Store Connect or Google Play, from macOS, Linux, or Windows. No Xcode, no Transporter, no Play Console upload dialog.

It's also the source of a very common misunderstanding: "I ran eas submit, so my app is submitted." Not quite. EAS Submit uploads your build. Getting it in front of users still involves a handful of steps that live in the store consoles, and those are where first launches stall.

This post covers both halves: how to set up EAS Submit properly for iOS and Android (including a recent change most older tutorials get wrong), and a clear map of what it doesn't do, so you can plan for it.

What EAS Submit does

  • iOS: uploads your .ipa to App Store Connect. The build appears in TestFlight after processing, usually 10 to 15 minutes. You don't need a Mac.
  • Android: uploads your .aab to a Google Play track (internal by default) and can roll it out, leave it as a draft, or publish to production, depending on your submit profile.
  • Automation: runs the same way locally, in EAS Workflows, or in any CI with an EXPO_TOKEN.

Setting up iOS

1. Bundle identifier and a production build

{
  "expo": {
    "ios": { "bundleIdentifier": "com.yourcompany.yourapp" }
  }
}
Enter fullscreen mode Exit fullscreen mode
eas build --platform ios --profile production
Enter fullscreen mode Exit fullscreen mode

2. A submit profile with your App Store Connect app ID

Create the app record in App Store Connect first. Then add its ID to eas.json:

{
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

You'll find the ID in App Store Connect → your app → App Information → Apple ID (a number, not your email).

3. An App Store Connect API key (for anything automated)

Interactive eas submit can prompt for your Apple ID. CI and workflows can't, so set up an API key once:

eas credentials --platform ios
# production → log in → App Store Connect: Manage your API Key
#            → Set up your project to use an API Key for EAS Submit
Enter fullscreen mode Exit fullscreen mode

If you prefer to manage the key yourself, set ascApiKeyPath, ascApiKeyIssuerId, and ascApiKeyId in the submit profile instead.

4. Submit

eas submit --platform ios --profile production
Enter fullscreen mode Exit fullscreen mode

Setting up Android

1. Package name and an .aab

{
  "expo": {
    "android": { "package": "com.yourcompany.yourapp" }
  }
}
Enter fullscreen mode Exit fullscreen mode
eas build --platform android --profile production
Enter fullscreen mode Exit fullscreen mode

The default production profile produces an Android App Bundle (.aab), which Google Play requires. An .apk profile is useful for installing on devices but can't be submitted.

2. Create the app in Play Console

EAS can't create the app record. Click Create app in Play Console and choose the package name.

3. A Google Service Account key

EAS needs a service account key to upload on your behalf. Create one (Expo links a step-by-step guide from its docs), then upload it:

eas credentials --platform android
# production → Google Service Account → Upload a Google Service Account Key
Enter fullscreen mode Exit fullscreen mode

4. A submit profile

{
  "submit": {
    "production": {
      "android": {
        "track": "internal",
        "releaseStatus": "draft"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • track picks where the build lands: internal, alpha (closed testing), beta (open testing), or production.
  • releaseStatus: "draft" uploads without rolling out, so you can review and release in Play Console.

5. Submit

eas submit --platform android --profile production
Enter fullscreen mode Exit fullscreen mode

The change older tutorials get wrong

For years, every Expo guide said the same thing: you must upload your first Android build manually in Play Console before EAS Submit will work. Expo's current docs say otherwise. On a first submission, the default eas submit works out of the box and creates the app's first release on the internal testing track, as long as the app exists in Play Console and EAS has your service account key.

The app stays in draft status in Play Console until you finish the store listing and setup tasks. Which brings us to the other half.

Build and submit in one step

eas build --platform all --profile production --auto-submit
Enter fullscreen mode Exit fullscreen mode

--auto-submit hands each finished build to EAS Submit using the submit profile with the same name.

Automate it with EAS Workflows

Workflows are YAML files in .eas/workflows/. This one builds both platforms on every push to main, sends iOS to TestFlight, and uploads Android to your configured track:

# .eas/workflows/release.yml
name: Release

on:
  push:
    branches: ['main']

jobs:
  build_ios:
    name: Build iOS
    type: build
    params:
      platform: ios
      profile: production

  build_android:
    name: Build Android
    type: build
    params:
      platform: android
      profile: production

  testflight:
    name: Send to TestFlight
    needs: [build_ios]
    type: testflight
    params:
      build_id: ${{ needs.build_ios.outputs.build_id }}

  submit_android:
    name: Submit to Google Play
    needs: [build_android]
    type: submit
    params:
      profile: production
      build_id: ${{ needs.build_android.outputs.build_id }}
Enter fullscreen mode Exit fullscreen mode

Run it manually the first time:

eas workflow:run release.yml
Enter fullscreen mode Exit fullscreen mode

The testflight job can also share the build with internal and external tester groups. If you'd rather use GitHub Actions or another CI, run eas submit there with an EXPO_TOKEN set.

What EAS Submit doesn't do

Here's the part that surprises people. After a successful eas submit, these steps still stand between your build and the public:

On iOS

Step Where
Submit the build for App Review App Store Connect
Store listing: name, subtitle, description, keywords, screenshots App Store Connect
App Privacy details (the "nutrition label") App Store Connect
Age rating questionnaire App Store Connect
Demo account for the reviewer, if login is required App Review Information
Beta App Review for external TestFlight testers (first build) Automatic, but it's a queue
Responding to rejections Resolution Center

EAS gets the binary into TestFlight. Sending it to App Review is still a step you take in App Store Connect.

On Android

Step Where
Store listing, screenshots, feature graphic Play Console
Data Safety form Play Console
Content rating questionnaire Play Console
Target audience, ads declaration, app access Play Console
Account deletion web link (if users can sign up) Data Safety form
12 testers for 14 days in closed testing (new personal accounts) Play Console + your testers
Applying for production access Play Console
Promoting a release to production Play Console, or track: "production" once allowed

The closed-testing requirement is the long one: new personal developer accounts must keep at least 12 testers opted in for 14 continuous days before production opens up. EAS can upload to the closed-testing track (track: "alpha") on every build, but the 14 days are calendar days.

A release pipeline that covers both halves

Put together, a realistic first launch looks like this:

  1. Day 1: create both app records; set up the ASC API key and Google service account key; add submit profiles.
  2. Day 1: first eas build --auto-submit. iOS lands in TestFlight; Android lands on the internal track.
  3. Days 1–3: recruit Android testers; switch the Android profile to track: "alpha" so every build goes to closed testing.
  4. Days 2–5: fill in listings, screenshots, privacy details, Data Safety, ratings, and the demo account.
  5. Day 5 onward: submit iOS for App Review from App Store Connect.
  6. Day 17 onward: apply for Google Play production access, then promote.

After launch, the pipeline is fully automatic: every merge to main builds, uploads, and lands in TestFlight and your Play track, and you promote from there.

Common EAS Submit errors

  • "No suitable application records were found" (iOS): the bundle ID doesn't match an app in App Store Connect, or ascAppId is wrong.
  • Version code or build number already used: set "cli": { "appVersionSource": "remote" } and "autoIncrement": true on the production build profile so EAS increments for you.
  • Service account permission errors (Android): the service account needs access to the app in Play Console's Users and permissions.
  • CI can't authenticate with Apple: interactive Apple ID login doesn't work in CI. Use the App Store Connect API key.

The short version

EAS Submit removes the upload step from your release. It doesn't remove the store consoles. Set up the API key and service account once, automate builds and uploads with a workflow, and put the listing, privacy, testing, and review steps on your calendar from day one.


If you'd rather hand off the console half (listings, privacy forms, Data Safety, testers, and the review back-and-forth), LetsDeployIt handles App Store and Google Play submission end to end.

What's the step that surprised you most on your first release?

Top comments (1)

Collapse
 
abhishek_goyal_c97dbf2eea profile image
Abhishek Goyal •

For HelperBook, my Android app on Google Play, the surprise wasn't the upload, it was R8. The release build shrinks code the debug build never touches, so I had to write keep rules for SQLDelight and kotlinx-serialization, or the database layer and the export format would have broken only in the build users get. The second was the Data Safety form: simple when all the data stays on the phone, but Crashlytics still has to be declared, so I kept names and amounts out of its logs to keep the answers true. Worth installing a signed release build on a real device before the first upload.