Expo Made Me Love Building iOS Apps.

I used React Native for speed, kept the native project after Prebuild, added Swift and entitlements in Xcode, and learned why EAS Build made the final step calmer.

The first time I opened one of my React Native apps on an iPhone with my own Swift service behind it, the stack finally made sense to me.

I love building iOS apps with Expo and React Native.

They let me move quickly without forcing me to choose between convenience and native control.

I can build almost the entire product in React and TypeScript, customise every part of the interface, and still open Xcode and write Swift when the app needs something deeper.

Expo gives me the fast road, but it never locks the native door.

From idea to an iPhone quickly

When I start a mobile product, I want to think about the experience first.

The screens. The interactions. The state. What happens when a user denies a permission, loses their connection, or returns after a week.

React Native gives me a productive component model for building those experiences. The interface is still completely mine. I control the layout, colours, typography, animation, navigation, and platform-specific behaviour. The result uses native platform views rather than rendering the app as a website inside a shell.

Expo then removes much of the setup surrounding that work. I can get the project onto a device quickly and keep iterating while the idea is still fresh.

My workflow was hybrid

I know Expo supports Continuous Native Generation, where the iOS and Android projects can be generated from app configuration and config plugins.

That is not exactly how I built my apps.

I ran Prebuild to generate the native projects, then kept the ios folder and treated it as part of the application.

When I needed iOS capabilities that went beyond the JavaScript layer, I opened the project in Xcode. I added the required entitlements, wrote the native service in Swift, and exposed it to the React Native side through an Objective-C bridging layer.

The TypeScript app could call the service like any other application API, while the actual platform work remained in Swift.

This gave me the exact balance I wanted:

  • React Native for most of the product.
  • Expo for the development and release workflow.
  • Xcode and Swift when iOS-specific features required them.

Expo did not limit the app

People sometimes talk about Expo as if it is useful only until an app becomes serious.

My experience was the opposite.

I could install libraries with native code, use a custom development build, modify the generated iOS project, add entitlements, write Swift, and bridge that functionality back into React Native.

I did not have to abandon Expo to do native work.

I simply dropped down one layer for the feature that needed it, then returned to the faster React Native workflow for everything else.

I stayed in TypeScript where it made me fast and used Swift where the platform made it necessary.

EAS Build made releases boring

That is a compliment.

An iOS build involves signing credentials, certificates, provisioning profiles, bundle identifiers, native dependencies, and a macOS build environment. None of those things make the product better, but a mistake in any of them can block a release.

EAS Build turned the project into a repeatable cloud build.

Because my native iOS project already existed, EAS built that project, including my Swift code, entitlements, bridge, and native configuration. It could also handle signing credentials and produce the iOS artifact without making every release depend on me repeating the same manual setup.

I still had control over the native project. I simply did not have to personally babysit every build.

Development builds kept iteration fast

Once native code enters the project, Expo Go is no longer enough because it does not contain that custom native functionality.

A development build does.

I could install my own development version of the app with its native dependencies and Swift service included. Normal React Native and TypeScript changes still appeared through the fast development loop. I needed a new native build only when the native code or configuration changed.

That kept ordinary product work quick without pretending native changes were ordinary JavaScript changes.

Expo does not hide iOS from me

This is why I enjoy the stack so much.

Expo handles the common path extremely well, but Xcode is still there when I need it. React Native lets me share the majority of the application, but platform-specific code is still available. EAS simplifies builds, but the generated result is still a real iOS application.

I am not trapped inside a template or restricted to a fixed set of device APIs.

I can start simple and increase the native complexity only when the product earns it.

It lets me stay close to the product

I do not love Expo because it removes engineering.

I love it because it removes avoidable friction.

I can spend more time shaping the interface, testing the experience, integrating the services, and shipping the next version. When iOS requires native work, I can write that work in Swift and connect it cleanly to the rest of the app.

Then EAS Build takes the complete project and turns it into something I can distribute.

React Native gave me speed. Swift gave me native control. Expo connected the two and let me stay focused on the product.