When building mobile applications with React Native and Expo, developers often praise the ecosystem for its rapid developer velocity. However, as projects mature and approach store deployment, a common concern emerges: Are you locked into Expo Application Services (EAS) Cloud, and will build and deployment costs scale out of control?
A recent community discussion on r/reactnative tackled this exact dilemma, unpacking how to run CI/CD pipelines, handle local builds, and manage Over-The-Air (OTA) updates without relying on Expo's paid cloud infrastructure.
The Core Dilemma: Is Expo a Vendor Lock-In Trap?
A developer reaching the publishing stage asked three critical questions:
- 1.
Can app bundles be built and distributed without Expo’s cloud?
- 2.
Do developers still need to "eject" to bare React Native to get full infrastructure control?
- 3.
Is Expo’s ecosystem designed to force developers into paid cloud pipelines?
The short answer from the community: No, you are not locked in, and no, you do not need to eject.
Key Community Answers & Technical Solutions
1. Local Builds and Custom CI/CD
You don't need EAS Cloud servers to generate release binaries (APKs, AABs, or IPAs).
Local EAS CLI Builds: As highlighted by community members, you can execute builds directly on your local machine or self-hosted CI runners (like GitHub Actions) using the
--localflag:Native Build Tools: Once prebuilt, the project generates standard
androidandiosdirectories. From there, standard native build tools—such as./gradlew assembleReleaseorxcodebuild—can be used directly, or integrated with automation platforms like Fastlane.
2. The Myth of "Ejecting"
Several community members emphasized that the concept of "ejecting" to bare React Native is largely obsolete.
Expo uses Continuous Native Generation (CNG). Through npx expo prebuild, Expo dynamically generates native project files based on your app configuration and Expo plugins. You retain full native control without losing the ability to maintain a clean Expo codebase.
Clarifying Community Questions: How to Self-Host OTA Updates
One of the most engaging sub-threads in the discussion raised an important follow-up:
Community Question: "How exactly do I self-host Over-The-Air (OTA) Updates without relying on Expo's update servers, and where are the resources for it?"
How Self-Hosted Expo OTA Updates Work
Expo’s update module (expo-updates) is client-side protocol agnostic. It makes HTTP GET requests to a designated update endpoint to check for new JavaScript bundles and assets.
To host your own OTA update server, you need:
- 1.
An HTTP server hosting your bundled assets and serving the updates protocol response header/JSON.
- 2.
Configuring
expo-updatesin yourapp.jsonto pointupdates.urlto your self-hosted server URL instead of Expo's servers.
Resources & Alternatives Mentioned:
Official Expo Guidance: Expo provides explicit documentation on the update protocol via their SDK Updates Documentation and maintains a reference implementation in the custom-expo-updates-server GitHub repository.
Open-Source Servers: Projects like expo-open-ota offer pre-built self-hosted update servers.
Final Takeaway
Expo’s EAS Cloud is designed for maximum convenience, but it is purely optional. By leveraging eas build --local, standard native tooling (Xcode/Gradle/Fastlane), and open-source OTA update protocols, developers can maintain full autonomy over their build pipelines and hosting costs while enjoying the developer experience of the Expo SDK.