A dependable React Native CI/CD workflow turns a release into a repeatable process instead of a last-minute checklist. This guide shows how to structure Expo environments, automated tests, EAS Build profiles, Android and iOS artifacts, signing credentials, preview channels, staged releases, and rollback plans. It also provides a simple estimation method for build volume, release effort, and maintenance cost so your team can revisit the plan when the app or delivery requirements change.
Overview
React Native CI/CD is the practice of validating, building, and distributing an app through an automated pipeline. A typical Expo-based workflow has four stages:
- Validate: Install dependencies, check TypeScript, lint the project, and run unit or component tests.
- Build: Create an Android or iOS binary with a defined environment and build profile.
- Verify: Give testers a preview build or update channel that is separate from production.
- Release: Submit the approved artifact to the appropriate app store, then monitor the rollout and keep a rollback path available.
Expo Application Services, commonly called EAS, can handle remote builds and connect those builds to a project’s signing credentials. The exact commands and service limits can change, so treat your project configuration and the current Expo documentation as the source of truth. The durable part of the workflow is the separation between environments, the checks that run before a build, and the approval required before production distribution.
Keep the application code and release configuration understandable. A useful project should make it obvious which profile creates a development client, which profile creates a preview artifact, and which profile creates a production build. Your navigation, authentication, and native integrations should also be tested in the same type of build that users will receive. For example, see the React Native authentication guide when protected routes or token handling are part of your release checks.
How to estimate
Before selecting a pipeline, estimate the work and usage it will create. This avoids treating CI/CD as a vague tooling expense and gives the team inputs it can update later.
Use these basic formulas:
- Monthly build count = preview builds + production builds + emergency rebuilds.
- Monthly platform builds = monthly build count multiplied by the number of platforms built per run.
- Release effort = preparation time + automated validation time + manual verification time + submission and monitoring time.
- Failure cost = failed-build investigation time + rerun time + any delayed release work.
- Release risk = affected users multiplied by the severity and duration of a bad release. Keep this as a relative planning measure rather than a precise financial forecast.
For each pipeline design, record the number of developers, expected pull requests, preview builds per change, production releases per month, target platforms, test duration, and the amount of manual approval required. Then compare that design with the manual process it replaces. A pipeline that uses more build minutes but removes repeated local steps may still be the better operational choice.
For costs, list each input separately rather than copying an old total: CI provider usage, EAS usage or plan requirements, artifact storage, test-device services, app-store developer accounts, and engineering time. Verify provider pricing and account fees when you calculate the total because those inputs are subject to change. The formula is more durable than any particular price:
Estimated monthly delivery cost = service usage costs + storage costs + account costs allocated per month + release maintenance hours multiplied by your internal hourly rate.
Inputs and assumptions
Environment and secrets
Define development, preview, and production environments explicitly. Public configuration, such as an API base URL that is safe to expose in a client, can be supplied through the app configuration. Secrets should remain in the CI or EAS secret store and should never be committed to Git or printed in logs.
Use separate credentials and service permissions where practical. A preview build should not accidentally point at a production database, send real notifications, or use production payment settings. Document which variables are required by each profile and fail early when a required variable is missing.
Build profiles and artifacts
A representative eas.json structure might include profiles named development, preview, and production. The development profile can support a development client, the preview profile can produce an installable tester artifact, and the production profile can create store-ready binaries. Keep the profiles small and explicit; hidden defaults are difficult to audit during an incident.
For Android, decide whether the pipeline needs an APK for direct installation or an AAB for store submission. These are different distribution needs, so do not use an APK as a substitute for every production workflow. For iOS, plan for a signed archive and the credentials required by the Apple distribution process. Test both platforms from CI even if one platform is currently the larger part of your user base.
Checks before building
Run formatting or lint checks, TypeScript validation, unit tests, React Native Testing Library tests where appropriate, and a production JavaScript bundle check. Add focused smoke tests for authentication, navigation, deep links, push notification registration, and native modules that could fail only in a device build. Performance-sensitive screens should also be checked on representative hardware; a green test suite does not prove that a long list scrolls smoothly. The React Native performance guide and FlatList performance guide provide useful follow-up areas.
Worked examples
Example 1: A small team with preview builds
Assume a two-developer project makes 20 pull requests per month, creates one Android and one iOS preview build for each approved change, and performs two production releases. The planning inputs are:
- 20 preview runs multiplied by two platforms = 40 platform builds.
- 2 production runs multiplied by two platforms = 4 platform builds.
- A planning reserve of 10% for failed builds and urgent rebuilds.
The team can use this estimate to check whether its chosen CI and EAS capacity is appropriate. If preview builds are expensive or slow, it might build both platforms only after review, while producing a single-platform artifact for earlier changes. That is a workflow decision, not a reason to remove tests.
Example 2: A production release with staged approval
Assume a team merges a feature on Monday, creates a preview build, tests login and deep links on physical devices, and records the result in the pull request. After approval, the production profile generates the Android and iOS artifacts. A release owner checks version numbers, permissions, icons, privacy text, environment variables, and store metadata before submission.
The release is then distributed to a limited audience or staged according to the store and product configuration. The team watches crash reports, authentication failures, and key business events. If the release is unhealthy, it stops the rollout and follows the documented rollback path. If the app uses over-the-air updates, only compatible JavaScript changes should be delivered that way; native changes require a new binary.
Example 3: A pipeline template
A platform-neutral pipeline can follow this sequence:
- Trigger on a pull request for validation.
- Install the locked dependency versions.
- Run lint, TypeScript checks, tests, and a bundle or configuration check.
- Build a preview artifact after the checks pass.
- Attach the artifact and test instructions to the change or release record.
- Require approval before starting a production build.
- Build Android and iOS with the production profile.
- Submit only after store metadata and signing checks are complete.
- Monitor the rollout and retain the previous known-good release information.
Keep signing credentials out of the repository. Let the build service manage them where appropriate, restrict access to production credentials, and document how an authorized maintainer can rotate or recover them. Never rely on one developer’s laptop as the only location for a keystore, certificate, provisioning profile, or store token.
When to recalculate
Review the estimate whenever an input changes. Recalculate after changing EAS or CI plans, pricing, build retention, test-device services, app-store account requirements, or the number of builds your team runs. Also revisit it when the team adds a platform, increases preview frequency, introduces native dependencies, changes its release cadence, or expands the production audience.
Use this recurring checklist before each release:
- Confirm the commit, version number, environment, and release notes.
- Verify that required secrets exist and are mapped to the intended profile.
- Run automated checks from a clean environment.
- Test the preview artifact on the supported Android and iOS versions and devices that matter to your users.
- Check signing credentials, bundle identifiers, package names, permissions, icons, and store metadata.
- Confirm that the Android artifact type is correct: APK for direct installation or AAB for the relevant store workflow.
- Confirm that the iOS build uses the intended bundle identifier and distribution credentials.
- Define who approves, submits, monitors, and can stop the rollout.
- Record the previous known-good version and the rollback or update path.
Once a month, compare estimated and actual build counts, failed runs, release hours, and incidents. Update the assumptions rather than judging the pipeline from a single release. As the app grows, link this process with your navigation, deep-linking, authentication, and TypeScript practices—for example, the Expo Router guide can help identify flows that deserve release smoke tests. A React Native CI/CD workflow stays useful when its inputs, ownership, and recovery steps remain visible.