EAS Build

Cloud builds without local Xcode pain.

9 minmedium

EAS Build is Expo's cloud build service. You push a config, EAS builds an iOS .ipa or Android .apk / .aab in its cloud, you download it. No Xcode on your machine required. This lesson covers the setup.

One-time install

Terminal
$npm install -g eas-cli
$eas login # uses your Expo account

The config — eas.json

Scaffolded into apps/mobile/eas.json:

apps/mobile/eas.json
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"distribution": "internal",
"android": { "buildType": "apk" }
},
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
}
}

Three profiles to know:

  • development — dev build, JS hot-reloads live. Use during day-to-day dev.
  • preview — APK / IPA you send to testers. Distributed via internal links.
  • production — what goes to the App Store / Play Store. Auto-increments build number.

Your first preview build

Terminal
# from apps/mobile/
$eas build --platform android --profile preview

First run prompts you to:

  1. Configure a project ID (one-time per project)
  2. For iOS: log in to Apple Developer account so EAS can sign with your cert
  3. For Android: pick auto-managed signing or upload your keystore

Then it queues the build. You get a URL to track progress. ~10 minutes later, downloadable APK / IPA.

Free tier: Expo gives you ~30 builds/month free, with queue priority on slow lanes. Paid tier ($29/mo) is faster queues + more builds. For a solo dev this is plenty.

Installing the preview build

  • Android APK: download, copy to phone, install (enable "install from unknown sources"). Or use the EAS QR.
  • iOS: you need TestFlight (covered in the next lesson) — APKs don't exist on iOS for unsigned distribution.

Versioning

Two numbers matter:

  • version (in app.json) — what the user sees ("v1.2.3"). Bump manually for marketing-visible releases.
  • build number / version code — internal monotonically increasing integer. EAS auto-increments with the production profile.

The store rejects builds with duplicate build numbers. Let EAS manage this.

What gets built into the binary

Build-time environment is locked in: app.json,app.config.ts, and any process.env baked in via extra in app.json. Runtime config (API URL, feature flags) flows through Constants.expoConfig.extra:

apps/mobile/app.config.ts
export default ({ config }) => ({
...config,
extra: {
apiUrl: process.env.EAS_API_URL ?? 'http://localhost:8080',
sentryDsn: process.env.EAS_SENTRY_DSN,
},
})

Set the env vars in EAS dashboard or with eas secret:create for per-profile secrets.

Quick check

You ran `eas build --profile production` but you forgot to bump the version. The build succeeds. What happens when you try to upload to TestFlight?

Try it

Produce your first preview build:

  1. Run npm install -g eas-cli if you haven't.
  2. eas login
  3. eas build:configure (one-time setup)
  4. eas build --platform android --profile preview
  5. Wait ~10 min, download the APK, install on your phone.
  6. Confirm the app launches and looks identical to the Expo Go version.

Paste the EAS build URL in notes.md.

What's next

Next lesson — submitting your build to the App Store and Play Store. The actual ship.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled — suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub