Skip to main content

Continuous Integration for React Native Apps with Fastlane and GitHub Actions

· 10 min read
Mobile Developer
Last updated on May 17, 2026

continuous integration on react native apps

Continuous integration for React Native should do more than run npm test. A useful pipeline protects every pull request, builds signed release artifacts from clean commits, keeps secrets out of the repository, and makes app store submission repeatable.

This guide covers a pragmatic CI/CD setup for modern React Native apps using GitHub Actions, EAS Workflows, EAS Build, EAS Submit, EAS Update, and fastlane. Use the parts that fit your project. Do not create three different release systems unless your team can operate all of them.

Quick Answer

For most React Native teams:

  1. Use GitHub Actions for pull request checks: install, typecheck, lint, unit tests, and lightweight static checks.
  2. Use EAS Build or EAS Workflows for signed iOS/Android builds when the app uses Expo modules or you want managed mobile build infrastructure.
  3. Use EAS Submit to upload app binaries to App Store Connect and Google Play when it matches your release process.
  4. Use EAS Update only for JavaScript and asset updates compatible with the installed native binary.
  5. Use fastlane when your team already has native lanes for signing, screenshots, metadata, TestFlight, Google Play tracks, or Firebase App Distribution.
  6. Store every signing key, API token, keystore, and service account credential in CI secrets or the provider's credential store.

If you are using an Instamobile React Native app, first review the Current React Native Stack and React Native App Release Checklist.

A healthy mobile CI/CD setup has separate gates:

GateRuns onPurpose
PR checksPull requestsCatch TypeScript, lint, unit test, formatting, and dependency issues early.
Preview buildLabels, manual trigger, or selected branchesGive QA a signed build from a known commit.
Release candidateMain/release branchBuild store-ready Android and iOS artifacts.
SubmissionManual approval or release tagUpload to Google Play/App Store Connect.
OTA updateCarefully selected commitsPublish compatible JS/assets only.

Do not submit to stores from every push to main. App store release should be a deliberate action with review notes, release notes, and rollback ownership.

Current React Native Baseline

For current Instamobile React Native apps, use the app package and the Current React Native Stack as the source of truth. In practice, CI should respect:

  • TypeScript-first source;
  • Yarn 4 through Corepack;
  • the Node version requested by the app;
  • the React Native and Expo module versions declared by the app;
  • the Android SDK and iOS deployment targets declared by the native projects;
  • Firebase Functions runtime requirements when backend functions are included.

The app package is still the source of truth. Check package.json, yarn.lock, ios/Podfile, android/build.gradle, android/app/build.gradle, and the app README before pinning CI images or commands.

GitHub Actions for PR Checks

Start with a small workflow that all pull requests must pass.

name: React Native Checks

on:
pull_request:
push:
branches:
- main

jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: yarn

- name: Enable Corepack
run: corepack enable

- name: Install dependencies
run: corepack yarn install --immutable

- name: Typecheck
run: corepack yarn typecheck

- name: Run tests
run: corepack yarn test --watch=false

Adjust script names to the app package. Some apps use lint, test, doctor, or verify; others only expose a focused set of scripts. Do not invent CI commands that the project does not have.

Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount 🔥

Get the Mega Bundle

Add Expo/EAS Checks

For apps that use Expo modules or EAS, add Expo validation after dependency installation:

      - name: Expo doctor
run: corepack yarn expo-doctor

If the app script is named differently, call that script instead:

corepack yarn doctor

Use expo-doctor as a compatibility signal, not as a replacement for running release builds on real devices.

Build With EAS

EAS Build is usually the cleanest path for React Native apps that use Expo modules, config plugins, EAS credentials, or cloud-managed signing.

Typical local setup:

npm install -g eas-cli
eas login
eas build:configure

Example eas.json shape:

{
"build": {
"preview": {
"distribution": "internal",
"channel": "preview"
},
"production": {
"channel": "production",
"android": {
"buildType": "app-bundle"
}
}
},
"submit": {
"production": {}
}
}

Build commands:

eas build --profile preview --platform all
eas build --profile production --platform all

Use preview builds for QA and production builds for app store artifacts. Keep profiles explicit so an internal test build cannot be confused with a store release.

Use EAS Workflows for Mobile Build Automation

EAS Workflows can run mobile-specific jobs on EAS infrastructure, including build, submit, update, and Maestro jobs. This is useful when you want mobile CI without maintaining macOS runners, Android SDK setup, or Xcode images yourself.

Use EAS Workflows for:

  • signed Android and iOS builds;
  • app store submission jobs;
  • OTA update jobs;
  • Maestro end-to-end smoke tests;
  • manual release workflows;
  • GitHub-triggered build jobs.

Keep GitHub Actions for generic repository checks if that is already your team standard, then delegate mobile artifact work to EAS.

Submit Builds With EAS Submit

EAS Submit uploads valid Android App Bundles and iOS IPAs to the store distribution pipelines.

eas submit --platform android
eas submit --platform ios

Build and submit in one flow:

eas build --platform all --profile production --auto-submit

Important release notes:

  • Android submissions go to the Google Play track you configure.
  • iOS submissions upload to App Store Connect and appear in TestFlight after processing.
  • TestFlight upload is not the same as App Store production release.
  • First-time Google Play API submissions may require manual Play Console setup first.
  • Store metadata, privacy, review notes, and screenshots still need human review.

Publish OTA Updates Carefully

EAS Update is useful for compatible JavaScript, styling, and asset changes. It is not a replacement for native builds.

Setup:

eas update:configure

Publish a production update:

eas update --channel production --message "Fix checkout button state" --environment production

Use the environment flag when your EAS setup separates preview, staging, and production variables. Check the current EAS Update docs before automating this step, because update requirements can change with Expo SDK releases.

Do not use OTA for:

  • native dependency changes;
  • permission changes;
  • entitlement changes;
  • app icon or splash changes;
  • React Native upgrades;
  • SDK upgrades;
  • payment or push native configuration changes.

For OTA strategy and CodePush migration context, read CodePush in React Native.

Where fastlane Still Fits

fastlane remains valuable for teams with mature native release lanes.

Good fastlane use cases:

  • custom iOS signing and Match;
  • uploading to TestFlight;
  • uploading Android App Bundles to Play tracks;
  • generating screenshots;
  • managing metadata;
  • distributing QA builds through Firebase App Distribution;
  • integrating with existing native release scripts.

Android lane example:

default_platform(:android)

platform :android do
lane :build_release do
gradle(
task: "bundle",
build_type: "Release",
project_dir: "android"
)
end
end

iOS lane example:

default_platform(:ios)

platform :ios do
lane :build_release do
setup_ci
app_store_connect_api_key(
key_id: ENV["APP_STORE_CONNECT_KEY_ID"],
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
key_content: ENV["APP_STORE_CONNECT_KEY_CONTENT"]
)
build_app(
scheme: "MyApp",
export_method: "app-store",
output_directory: "build",
output_name: "MyApp.ipa"
)
end
end

If you choose fastlane, keep the lane names boring and explicit: build_android_release, submit_android_internal, build_ios_release, upload_ios_testflight. Ambiguous names like deploy become risky over time.

Secrets and Credentials Checklist

Never commit these:

  • Android upload keystore;
  • keystore passwords;
  • Google Play service account JSON;
  • App Store Connect API key private key;
  • provisioning profiles or certificates unless stored intentionally through a secure signing system;
  • Firebase service account files;
  • Expo access tokens;
  • Stripe, Twilio, OpenAI, or other provider secrets;
  • .env files containing private values.

Store secrets in:

  • GitHub Actions secrets;
  • EAS secrets/environment variables;
  • fastlane Match private storage;
  • cloud secret managers;
  • CI provider secret stores.

Be careful with pull requests from forks. Do not expose signing or submission secrets to untrusted PR workflows.

GitHub Actions + EAS Example

This pattern keeps PR checks in GitHub Actions and uses EAS only for release operations.

name: React Native Release Candidate

on:
workflow_dispatch:
inputs:
profile:
description: EAS build profile
required: true
default: preview

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: yarn

- name: Enable Corepack
run: corepack enable

- name: Install dependencies
run: corepack yarn install --immutable

- name: Typecheck
run: corepack yarn typecheck

- name: Setup Expo and EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: Build with EAS
run: eas build --profile "${{ inputs.profile }}" --platform all --non-interactive

For production submission, use a separate manual workflow with an approval step or a protected environment. Keep production submission out of normal PR checks.

Release Gates Before Store Submission

Before CI uploads to App Store Connect or Google Play:

  • corepack yarn install --immutable passes.
  • TypeScript passes.
  • Unit tests pass.
  • Native config points to production app identifiers.
  • Firebase config files are production-ready.
  • Firestore/Storage rules and Functions are deployed where needed.
  • App Check, push, payments, maps, media upload, and auth are tested where included.
  • Android App Bundle is signed and targets the required API level.
  • iOS archive uses the production bundle ID and signing team.
  • Store metadata, privacy forms, screenshots, and review notes are ready.
  • Rollback/hotfix owner is assigned.

CI can enforce some of these. The rest should live in the release checklist because they require product and account context.

Common CI Failures

FailureLikely cause
Works locally but fails in CI installCorepack/Yarn version mismatch or lockfile drift.
Android build cannot signMissing keystore secret, wrong alias, or wrong Gradle property names.
iOS build fails on CI onlyWrong Xcode image, missing signing identity, or provisioning mismatch.
EAS Update reaches wrong usersChannel/profile mismatch or missing runtime version discipline.
Store upload works but review failsPrivacy, app access, metadata, screenshots, or policy forms incomplete.
PR from fork cannot access secretsExpected security behavior; do not weaken it for signing workflows.
Looking for a custom mobile application?

Our team of expert mobile developers can help you build a custom mobile app that meets your specific needs.

Get in Touch

FAQ

Should React Native apps use GitHub Actions or EAS Workflows?

Use GitHub Actions for general repository checks when your team already works in GitHub. Use EAS Workflows for mobile-specific build, submit, update, and E2E jobs when you want Expo-managed mobile infrastructure.

Do I still need fastlane if I use EAS?

Not always. EAS can handle build and submit workflows for many teams. Keep fastlane when you already rely on native lanes for signing, metadata, screenshots, TestFlight, Google Play tracks, or Firebase App Distribution.

Can CI publish OTA updates on every merge?

Technically yes, but it is risky. OTA updates should still respect runtime compatibility, QA, release notes, monitoring, and rollback rules.

Should store submission be automatic?

Store upload can be automated, but production release should usually require a manual approval gate. App stores involve policy, metadata, privacy, and support readiness, not only a build artifact.

Conclusion

React Native CI/CD works best when each tool has a clear job. Let GitHub Actions protect pull requests, let EAS or fastlane build signed mobile artifacts, keep store submission behind deliberate release gates, and reserve OTA updates for compatible non-native fixes.

The goal is not maximum automation. The goal is a release process that produces the same trusted artifact from the same commit, keeps secrets safe, and gives your team a fast path from issue to verified fix.