Building cross-platform apps with React Native used to hit an immediate hardware bottleneck: if you didn't own a physical Mac, compiling an iOS .ipa binary was virtually impossible without brittle hackintoshes or expensive rented cloud desktops.
Expo Application Services (EAS) solves this friction point. Through remote cloud workers, EAS Build packages native binaries for both operating systems directly from your terminal, regardless of your local machine. Coupled with EAS Update, you can fix production bugs instantly via Over-The-Air (OTA) runtime patches without waiting for App Store or Google Play reviews.
Here is how to set up both workflows from scratch using EAS's generous free tier.
1. Prerequisites and Installation
Ensure you have Node.js installed alongside a standard React Native or Expo project. Install the EAS CLI globally:
npm install -g eas-cli
Log in or register an account on Expo:
eas login
Navigate to your project root and link it to your EAS account:
eas init
This creates an association in your app.json with an EAS project ID.
2. Configuring Cloud Builds with eas.json
EAS configuration lives in an eas.json file at the root of your project. Run the setup generator:
eas build:configure
This generates a boilerplate file. Modify your eas.json to define realistic development, preview, and production profiles:
{
"cli": {
"version": ">= 12.0.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"distribution": "internal",
"android": {
"buildType": "apk"
},
"ios": {
"simulator": true
}
},
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
}
}
Key insight: By default, Android builds produce an
.aab(Android App Bundle) designed for the Play Store. Setting"buildType": "apk"in your preview profile outputs a standalone.apkfile that you can install directly on test devices via USB or browser download.
3. Triggering Cloud Builds (No Mac Required)
To build a native iOS binary without running Xcode locally, invoke:
eas build --platform ios --profile preview
EAS handles the entire code signing workflow interactively:
- If you don't have an iOS Distribution Certificate or Provisioning Profile, EAS prompts to log in to your Apple Developer account.
- EAS generates and stores the certificates securely in Expo's cloud vault.
- The project bundles, uploads to an isolated macOS runner, runs native compilation, and returns a download link for your
.ipaor simulator tarball.
For an installable Android APK:
eas build --platform android --profile preview
EAS can automatically generate and manage your Android keystore credentials, taking the friction out of native certificate handling.
4. Bypassing Store Reviews with EAS Update (OTA)
Binary builds are required when adding new native dependencies or editing app permissions. However, if your changes are limited to JavaScript, TypeScript, or asset updates (e.g., UI tweaks, logic bug fixes), building a full binary is unnecessary.
Initialize EAS Update in your project:
eas update:configure
Verify that app.json includes the runtime configuration:
{
"expo": {
"updates": {
"url": "https://u.expo.dev/<YOUR_PROJECT_ID>"
},
"runtimeVersion": {
"policy": "appVersion"
}
}
}
Pushing an Instant Hotfix
When a bug occurs in production, patch your code and deploy directly to user devices:
eas update --branch production --message "Hotfix: resolve checkout crash"
The update compiles the JS bundle and assets, syncs them to Expo's CDN, and marks them for distribution. The next time users open the application, the new bundle downloads silently in the background and applies on the subsequent launch.
5. Staying Efficient on the Free Tier
Expo's free tier provides 30 build credits per month across Android and iOS, with priority queues reserved for paid tiers. Optimize your monthly usage with these practices:
-
Use local development clients: Run
npx expo startfor standard iteration instead of triggering a new build for every change. - Rely on EAS Update for JS changes: Never spend a build credit on a UI color change, typo, or JavaScript logic tweak.
-
Use the
ios.simulatorflag: iOS simulator builds finish faster and don't require an active paid Apple Developer account to test on macOS emulators.
EAS transforms mobile development from a heavy local infrastructure challenge into a clean command-line operation.
Top comments (0)