Steps to Set Up EAS:
The EAS config file for the project is eas.json. In here we use profiles to determine the type of application we want to build. If you want the application to be downloaded for pre-release testing and UAT etc the `distribution` field in the profile needs to be set to `internal` so this can be downloaded via the link on test devices (iOS devices need to be added to the provisioning profile).
Provisioning profiles and signing certificates are generated and handled by EAS so we don't need to manually change these. If you need to update the provisioning profile because a new device has been added, you need to choose the option to create a new one when you run the `eas build` CLI.
Get started
Install the EAS CLI npm i -g eas-cli
Create project in expo.dev and copy id
Login to your EAS account with`eas login
Run eas init —id {projectID} in your project root to initialise the EAS configuration
Make sure the "owner" and "slug" key values are added below "extra" object in app.json and Initialise your EAS build configuration with eas build:configure
Add certificates and signing keys to Project > Configuration >Credentials https://expo.dev/accounts/{account-name}/projects/{project-name}/credentials
Add SSH_KEY_BASE64 key to a .env file and add env variables from .env to the project EAS secrets with eas secret:push --scope project --env-file .env –force
Create your first build with eas build
If you want to use local credentials like device provisioning and keystore you need to specify these in the `credentials.json`. All reference to credentials should be .gitignored
Build steps:
Checkout the branch you want to build (i.e staging or production)
Run `eas build --profile [staging|production]`
Follow through the CLI and create builds for both platforms
The build will then be uploaded to EAS and you can track the progress via https://expo.dev/accounts/thedistance/projects/[project name]
When build is complete, it can be distributed to provisioned devices by sending them the link to the build or the QR code.
EAS Versioning
We can let EAS manage the versioning of our apps and skip this previously manual task.
Update app.json
"cli": {
"appVersionSource": "remote",
. . .
"build": {
"production": {
"autoIncrement": true
}
Set remote buildNumber, versionCode to start from with eas build:version:set
This lets EAS manage the buildNumber/versionCode increament.
EAS Submittion to Stores
Google Play Internal Track (Android)
For submitting to the Google Play internal track, you will need the Google Service Account JSON. This JSON will give permission to EAS to upload builds.
Setup steps on this guide
https://github.com/expo/fyi/blob/main/creating-google-service-account.md
1. Go to Google Cloud Console - Service accounts
2. Create new account - this produces and autodownloads the json
3. Copy email of service account
4. Add email as user with access to the app in Google Play Console - Users and Permissions enabling Releases permissions
eas build --platform android --profile production --auto-submit
TestFlight (iOS)
For TestFlight, you need to 2set up App Store Connect API keys, which are also managed in your App Store Connect account under Users and Access -> Keys. You can store the necessary App Store Connect credentials (e.g., App Store Connect API key, issuer ID) in EAS Secrets.
https://github.com/expo/fyi/blob/main/creating-asc-api-key.md
Create key, download and add to 1Password with name "AppStore Connect Auth Key for EAS Submit"
Add Issuer ID, Key ID and the .p8 file to EAS Credentials
eas build --platform ios --profile production --auto-submit
For years, App Center has been a go-to tool for managing builds and deployments, but with Microsoft pulling the plug by March 31, 2025, it’s time to find an alternative. Like many others, we had to figure out what came next - and fast.
But this wasn’t just about replacing a tool. It was about finding something better. Something more reliable, efficient, and future-proof. After exploring our options, we landed on Expo Application Services (EAS). Making the switch wasn’t without its challenges, but in the end, it transformed the way we handle app distribution. Here’s what we learned along the way.