Moving from local development to a live production environment is often the most stressful part of mobile development. If you’re wondering How to Deploy Expo App to App Store, you’ve likely realized that while Expo makes development a breeze, the Apple ecosystem requires a very specific set of credentials and configurations. This guide walks through the process from start to finish, with the commands and checks I use on my own projects.

In my experience, the transition from the Expo Go app to a standalone binary is where most developers hit a wall. Whether you are using the Expo Router tutorial for beginners to build your navigation or you’re coming from a more complex setup, the deployment pipeline remains the same. Today, we use EAS (Expo Application Services), which has fundamentally changed how we handle certificates and builds. Expo Go is only for development previews. The App Store needs a signed, standalone build, and EAS produces that for you.

Prerequisites

Before we touch a single line of code, you need these three things in place. Without them, you cannot publish to the App Store:

Step 1: Configure your app.json

Your app.json (or app.config.js) is the source of truth for your app. You need to provide a unique bundle identifier that Apple uses to identify your app globally. Choose it carefully: once an identifier is registered and used for an App Store listing, it cannot be changed for that app. Use a reverse-domain style name you control, and keep the version field as the user-facing version string.

{
  "expo": {
    "name": "My Awesome App",
    "slug": "my-awesome-app",
    "version": "1.0.0",
    "ios": {
      "bundleIdentifier": "com.yourname.myapp",
      "buildNumber": "1",
      "supportsTablet": true
    },
    "extra": {
      "eas": {
        "projectId": "your-project-id-from-expo"
      }
    }
  }
}

The buildNumber is a separate counter that App Store Connect uses to tell uploads apart. It is a string, and each upload for the same version must have a higher build number than the last. Later, the autoIncrement option in eas.json can manage this for you.

If you’re still debating why use Expo instead of React Native CLI, this is exactly why: EAS handles the complex Xcode project generation for you in the cloud.

Step 2: Initialize EAS Build

Run the following command in your project root to set up your build configuration:

eas build:configure

This creates an eas.json file. I recommend setting up a specific production profile to ensure your app is optimized for the store. The distribution value store tells EAS to produce a build meant for App Store submission rather than an internal test build. Your eas.json should look something like this:

{
  "build": {
    "production": {
      "distribution": "store",
      "autoIncrement": true
    }
  }
}

It also helps to add a preview profile with "distribution": "internal" for testing builds. You will use that later for TestFlight-style testing, so you can keep production builds separate from experiments.

Step 3: Running the Production Build

Now we trigger the build. This is where the magic happens. Instead of needing a Mac with Xcode installed locally, Expo’s servers will spin up a macOS VM, install your dependencies, and compile the binary. You can close your laptop and check back later, since the build runs on Expo’s servers.

eas build --platform ios --profile production

During this process, EAS will ask you to log into your Apple Developer account. Pro Tip: Let EAS handle the credentials. It will generate your Distribution Certificate and Provisioning Profile automatically. I’ve tried doing this manually in the past, and it’s a recipe for ‘Invalid Signature’ errors. If you already have certificates from another tool, EAS can detect them, but check the credentials section in the Expo dashboard before you rely on them.

Once the build starts, you can follow the progress in your terminal or via the Expo dashboard. When the build finishes, EAS gives you a link to the artifact and its build logs. If it fails, the logs usually point to the exact step, such as a failed dependency install or a missing native configuration, so start there before changing anything else.

Step 4: Submitting to App Store Connect

Once your build is finished, you have a .ipa file sitting on Expo’s servers. You can manually download it and use Transporter, but the fastest way is using the EAS submit command:

eas submit -p ios

This pushes your binary directly to App Store Connect. EAS will ask which build to submit and will use your Apple credentials to authenticate. The first time, you may need to create the app record in App Store Connect with the same bundle identifier you set in app.json, otherwise the upload will fail with a mismatch error.

From here, you just need to log into the web portal, fill out your app descriptions, upload screenshots, answer the export compliance and privacy questions, and submit for review. Apple’s review time varies, so plan releases with some buffer.

Automating Builds with CI/CD

Once your first release is out, you will want to stop running builds by hand. A CI/CD pipeline can build and submit your app whenever you push a release tag. The main requirement is an Expo access token, which you store as a secret in your CI provider, not in your repository.

Here is a minimal GitHub Actions example that builds and submits on a version tag. It assumes you have already run the interactive build once so that EAS has your iOS credentials:

name: Release iOS
on:
  push:
    tags:
      - 'v*'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
      - run: eas build --platform ios --profile production --non-interactive
      - run: eas submit --platform ios --latest --non-interactive

Create the EXPO_TOKEN secret from your Expo account settings. Use --non-interactive so the job fails clearly instead of waiting for a prompt that will never be answered. If you want to add a review step, split the build and submit into separate jobs and require manual approval before the submit job runs.

Expo Export vs. EAS Build

People often search for expo export when they want to deploy, but it does something different. npx expo export generates the JavaScript and asset bundles for your app, and it is useful for checking what will ship or for hosting a web build. It does not create a signed iOS binary and it does not submit anything to App Store Connect. For the App Store, you still need eas build with a store profile and then eas submit.

If you are looking for a deploy command, the App Store path is the build and submit flow above. Over-the-air updates, covered below, are a separate mechanism that sends JavaScript changes to existing installs without a new store submission.

Pro Tips for a Smooth Approval

Troubleshooting Common Errors

Error Cause Solution
Bundle ID mismatch The ID in app.json doesn’t match App Store Connect Ensure bundleIdentifier is identical in both places.
Missing Icon Icon file missing or wrong format Check expo.icon path and ensure it’s a PNG.
Build Timeout Too many heavy dependencies Check for unused packages or upgrade your EAS plan.
Invalid Signature Manually created or outdated certificates and profiles Let EAS manage credentials, or inspect them in the Expo dashboard and regenerate them through EAS.
Build number already used The submitted build number was not higher than an existing upload Increase buildNumber or enable autoIncrement in your production profile.

How to Deploy Expo App to App Store: What's Next?

Once your app is live, the work doesn’t stop. I highly recommend setting up OTA (Over-the-Air) Updates. With eas update, you can push bug fixes and JavaScript changes to users without a new store submission. This is a game-changer for productivity, but it only covers JavaScript and assets. Changes to native code, new permissions, or new native modules still need a new binary built and submitted through the process above, so keep that distinction in mind when you plan a release.

Official resources for How to Deploy Expo App to App Store

Documentation and references for How to Deploy Expo App to App Store: