Skip to main content
Tutorial

Expo EAS Build: How I Set Up CI/CD for My React Native Apps

5 min read

Step-by-step walkthrough of setting up Expo EAS Build for CI/CD in React Native apps, based on 5 years of shipping UAE-region projects

React NativeCI/CDExpoUAE developmentDevOps

Last month, I was scrambling to meet a deadline for Greeny Corner—a plant care app I built using React Native and Expo SDK 54. The client wanted a new Arabic language feature shipped to the UAE App Store in 48 hours. My local builds worked fine, but when I triggered the first EAS Build workflow in GitHub Actions, the iOS pipeline exploded with a cryptic code signing error. Three cups of Arabic coffee and six hours later, I figured it out. This isn't how I planned to spend my night. But that battle with EAS Build taught me how to build bulletproof CI/CD pipelines for React Native apps—without losing my sanity.

Why I Stopped Using Manual Builds

I used to do everything locally: eas build commands, then waiting 15 minutes per platform while my laptop fan screamed. It worked for small projects like a proof-of-concept for a Dubai logistics company. But with real clients—like the Abu Dhabi real estate agency that needed urgent bug fixes for their bilingual listing app—this became unsustainable.

Expo’s EAS Build offered something better: auto-scaled workers, consistent build environments, and no more "works on my machine" issues. The catch? Getting from "It should work" to "It actually works" requires wrestling with configuration files like eas.json and GitHub Actions workflows that don’t behave the way you expect.

Setting Up EAS Build for CI/CD: The Real Steps

  1. Install and Configure EAS on Your Machine First

I started by running npm install -g eas-cli && eas login. If your project uses Expo SDK 54 (like Greeny Corner), run eas build:configure to generate the correct configuration files.

  1. Create Separate Build Profiles

Here's what my eas.json looks like for most projects:

`json

{

"build": {

"preview": {

"android": { "buildType": "apk" },

"ios": { "enterpriseProvisioning": "universal" }

},

"production": {

"ios": {

"distribution": "app-store",

"provisioningProfilePath": "credentials/ios_production.mobileprovision"

}

}

}

}

`

The key here? Don’t use the same profile for development and production builds. The last time I tried that for a Laravel + React Native project, I ended up uploading a debug build to the App Store. My client wasn’t happy.

  1. Connect GitHub Actions to EAS

I’ve tried multiple CI tools, but GitHub Actions works best with Expo. Start by setting up a personal access token in your repository settings. Then create .github/workflows/main.yml:

`yaml

name: Run EAS Build

on:

workflow_dispatch:

push:

branches:

- ci-cd

jobs:

build:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

- run: touch .easignore

- run: eas build --platform all

`

The touch .easignore line is a hacky but necessary step—the CLI errors if it doesn’t exist, even if you don’t need custom rules.

How I Handle Environment Variables and Secrets

If you thought managing .env files in React Native was bad before EAS, try automating it without exposing secrets. For a financial app I built in Doha last year, I had to do this the right way:

  • Step 1: Store sensitive values (API keys, certificates) in GitHub Secrets.
  • Step 2: Add non-sensitive environment variables to app.json:

`json

{

"expo": {

"name": "Project Name",

"plugins": [

[

"expo-build-properties",

{

"ios": {

"resourceClass": "m2"

}

}

]

]

}

}

`

  • Step 3: Inject secrets at build time using GitHub Actions:

`yaml

- run: eas build --platform ios --non-interactive

env:

API_KEY: ${{ secrets.API_KEY }}

`

Be warned: EAS caches builds aggressively. I once spent four hours tracking down a bug caused by an old cached variable. Use eas build:clear whenever in doubt.

Common Issues That Wasted My Hours

Missing iOS Provisioning Profiles

This one bit me during the Greeny Corner crunch. For UAE iOS deployments, I now do this every time before building:

bash
eas build:configure --platform ios
eas credentials --platform ios

Expo's automated credentials management works 60% of the time. The other 40% requires manually uploading .mobileprovision files from the Apple Developer portal.

Android Keystore Mismatches

Never lose access to your signing key. Once I uploaded a release build with a test keystore for a client in Riyadh. We had to remove the app from Play Store and relaunch it under a new package name. Here's how to back up your key:

bash
eas build:submit --platform android --skip-confirmation
keytool -list -v -keystore ./release-key.keystore

Frequently Asked Questions

### Can I Use EAS Build with Expo Router Apps?

Yes. As long as you're using SDK 47 or higher (like in my UAE SEO checklist), EAS supports app directory structure projects out of the box. Just make sure your navigation routes work across platform boundaries.

### Do I Need GitHub Actions or Can I Use Other CI Tools?

GitHub Actions just happens to be what I use daily. For a healthcare app in Kuwait, I configured EAS Build on GitLab CI instead. Same principles apply: version control triggers builds, and secrets get injected through the pipeline.

### How Do I Test EAS Build Before Automating?

Run eas build --local to test Android builds on your machine. You still need a macOS machine for iOS builds though. For clients who don't understand why iOS takes longer: tell them Apple decided to make things "extra special".

### My EAS Dev Build Keeps Crashing After Setup—Why?

Check if you imported a third-party module that requires native linking. It happened to me with react-native-google-maps on a Riyadh transportation app. EAS DevClient can't auto-link native modules the same way Expo Go does—you'll need to create a custom development client.

Want Help Setting Up EAS Build?

CI/CD pipelines can be a pain in the ass when you’re juggling three client deadlines and a flight to Jeddah. If you'd like to skip the headaches and get this working the first time, book a free consultation to discuss your project. I’ve done this for 40+ apps across the Gulf, and I know exactly where the traps are hiding.

S

Sarah

Senior Full-Stack Developer & PMP-Certified Project Lead — Abu Dhabi, UAE

7+ years building web applications for UAE & GCC businesses. Specialising in Laravel, Next.js, and Arabic RTL development.

Work with Sarah