Mobile Development

The Expo Architecture Decision Guide: Prototyping to Production

A deep technical dive into Managed Workflows, Continuous Native Generation, and the reality of shipping React Native at scale.

Stop treating Expo as a prototyping tool. Learn how to leverage EAS Build, Config Plugins, and OTA updates to ship production-grade mobile apps with 50% less native overhead.

AN
Arfin Nasir
Apr 11, 2026
6 min read
0 sections
The Expo Architecture Decision Guide: Prototyping to Production
#Expo#React Native#Mobile Architecture#DevOps
Technical Deep Dive

The Expo Architecture Decision Guide

Moving from "it's just for prototypes" to "it's how we ship enterprise scale."


For years, a specific stigma haunted React Native development: "Expo is great for hobby projects, but you have to eject for real work." This binary thinking caused teams to waste months configuring Gradle files and fighting Xcode schemes when they should have been shipping features.

The landscape has shifted. With the introduction of Continuous Native Generation (CNG) and EAS Build, Expo has evolved from a runtime wrapper into a full-stack mobile platform. It abstracts the complexity of native builds without abstracting away the control you need.

The goal of modern mobile architecture isn't to write native code; it's to write business logic that runs natively.

— Modern Mobile Philosophy

In this guide, we will dismantle the old myths and build a mental model for using Expo in high-stakes production environments. We will cover the architecture of expo-dev-client, the power of Config Plugins, and how to implement a CI/CD pipeline that rivals native iOS/Android teams.

1. The Architecture: How Expo Actually Works

Many developers visualize Expo as a "black box." In reality, it is a transparent layer of abstraction over standard React Native. Understanding these layers is critical for debugging.

Your React Native Code (TS/JS) Components, Hooks, Business Logic Expo SDK & Unimodules Camera, Maps, Auth, File System (Pre-linked) Native Runtime (iOS/Android) Standard React Native Core + Expo Go / Dev Client Config Plugins Modify Layer 3 from Layer 1

Key Takeaway: Expo does not replace React Native. It sits on top of it. The "Managed Workflow" simply locks the bottom layer (Native Runtime) to prevent accidental breakage, while Config Plugins allow you to modify that layer declaratively.

2. The Workflow Shift: From "Ejecting" to CNG

The old workflow was dangerous. If you needed a specific native library not supported by Expo, you had to "eject." This created a ios/ and android/ folder in your repo that you were now responsible for maintaining. Merge conflicts in Info.plist or AndroidManifest.xml became a weekly nightmare.

Continuous Native Generation (CNG) solves this. Instead of committing native folders, you commit a configuration file (app.json or app.config.js). During the build process on EAS (Expo Application Services), the native projects are generated on the fly based on your config.

Why this matters: You get the flexibility of a bare React Native app without the technical debt of maintaining two massive native codebases in version control.

Comparison: Traditional vs. CNG Workflow

❌ Traditional Bare Workflow

  • Commit ios/ and android/ folders (10k+ files).
  • Manual linking of native modules.
  • High risk of merge conflicts in build scripts.
  • Requires Xcode/Android Studio for every config change.

✅ Expo CNG Workflow

  • Commit only app.json and JS code.
  • Config Plugins handle linking automatically.
  • Native code is generated clean every build.
  • Configure permissions and icons via JSON.

3. Visualizing Config Plugins

How does a JSON file change native code? Config Plugins are functions that run during the pre-build phase to inject native configuration.

// app.config.js (Your Input)
export default {
  name: "MyApp",
  plugins: [
    ["expo-camera", {
      cameraPermission: "Allow $(PRODUCT_NAME) to access your camera"
    }]
  ]
}
↓ EAS Build Process (Pre-build) ↓
// Generated: ios/MyApp/Info.plist (Snippet)
<key>NSCameraUsageDescription</key>
<string>Allow MyApp to access your camera</string>

// Generated: android/AndroidManifest.xml (Snippet)
<uses-permission android:name="android.permission.CAMERA" />

The Magic: You never touch the XML or Plist files directly. If you need to update the permission string, you change the JS config, and the native files are regenerated cleanly on the next build.

4. The Killer Feature: Over-The-Air (OTA) Updates

In the traditional App Store model, fixing a critical bug involves:
Fix Code → Build Binary → Submit to Review → Wait 24-48hrs → User Updates.

With EAS Update, you can push JavaScript and asset changes instantly to your users, bypassing the store review process entirely. This is not just a convenience; it is a risk mitigation strategy.

Warning: OTA updates cannot change native code. If you update a native library (e.g., upgrading react-native-reanimated), you still need a full binary build via EAS Build.

The OTA Update Pipeline

Dev npx eas update EAS Servers Host Bundle Manifest Check User App Running v1.0 Download JS User App Running v1.1 (Instant)

How it works: The app checks the manifest on launch. If a newer JavaScript bundle exists on the server, it downloads it in the background and swaps it on the next reload. Zero downtime for the user.


5. Implementation Checklist & Decision Framework

Should you use Expo? For 95% of React Native projects, the answer is yes. However, you must choose the right flavor of Expo. Use this framework to decide.

Which Workflow Do You Need?

  1. Start with Managed Workflow.
    Use npx create-expo-app. Do not create ios/ or android/ folders. Use Config Plugins for any native needs (icons, permissions, deep links).
  2. Need custom native code?
    If you need to write Swift/Kotlin code that isn't a library, create a Development Build (expo-dev-client). This gives you a custom version of Expo Go that includes your native modules.
  3. Avoid "Ejecting" (Bare Workflow).
    Only eject if you are integrating a legacy native SDK that explicitly forbids being loaded within the Expo runtime (extremely rare in 2024).

"The best mobile architecture is the one that lets you iterate on Friday and ship on Monday, not the one that requires a PhD in Gradle."

6. Common Pitfalls to Avoid

Hardcoding Native Paths

Never import from ../../ios/.... Always rely on the module resolution provided by the package. Hardcoded paths break CNG.

Ignoring Asset Optimization

OTA updates are limited by size. Use expo-asset properly and optimize images. Large bundles slow down the update download significantly.

Skipping Staging Channels

Don't push OTA updates directly to production. Use EAS Update channels (preview, production) to test updates on real devices before rolling out.


Frequently Asked Questions

Can I still use CocoaPods and Gradle?

Yes, but indirectly. With CNG, you don't edit the Podfile directly. Instead, you use Config Plugins to inject the necessary pod dependencies into the generated Podfile during the build process.

Does Expo increase app size?

Historically, yes, because it included everything. With Expo Development Builds, the app size is nearly identical to a bare React Native app because it only includes the specific native modules you configure.

Is Expo suitable for banking/enterprise apps?

Absolutely. Major companies like Shopify, Discord, and Tesla use Expo. The security model is robust, and the ability to patch vulnerabilities via OTA is a massive advantage for enterprise security teams.

Ready to Modernize Your Mobile Stack?

I help teams build production systems with Expo. From migrating legacy bare RN apps to setting up robust EAS CI/CD pipelines, I ensure your mobile architecture scales.

Explore Portfolio & Consulting

Want to work on something like this?

I help companies build scalable, high-performance products using modern architecture.