
For years, one of the most common and most heated debates in the React Native community has been the choice between the Bare Workflow and Expo's Managed Workflow. If you've spent any time building mobile apps, you've either actively participated in this argument or desperately tried to avoid it.
I used to be firmly planted on one side: I built everything in the bare workflow. I loved the raw native control, and honestly? I hated Expo's restrictions. Today, I want to tell you why that changed and why I was wrong.
Work with React Native long enough and you'll inevitably hear the question: "Bare workflow or Expo, which should I use?"
It came up constantly in my circles. In particular, I have a friend, Samuel, who is a massive Expo enthusiast. We regularly talk shop about projects, architecture decisions, and best practices.
Those conversations always followed the exact same script: He loved Expo. I hated it. He tried to convince me. I ignored him.
I was comfortable using the bare workflow. I knew my way around Xcode, Android Studio, Gradle files and native configs. In my head, Samuel was that guy: overly enthusiastic, slightly annoying, and definitely wrong. So, I didn't give his arguments much attention. At least, not at first.
Before we get to the "aha!" moment, let's take a step back and look at why I was so stubborn to begin with.
React Native is fantastic. It gives you the developer experience of React with a near-native user experience. And since the New Architecture became the default, doing away with the old asynchronous JSON bridge in favour of synchronous calls, that gap has only kept closing. But when people talk about the "bare workflow" they mean plain React Native with unfiltered, raw access to the native code.
That level of access comes with some extreme highs and agonizing lows.
With the bare workflow, you fully own the project. No abstraction layers hiding the magic from you and no surprises. You have complete access to both the iOS and Android native codebases. You can:
If something is possible on iOS or Android, you can do it in the bare workflow.
That power comes at a steep cost. You are entirely responsible for managing your build tools, native dependencies, and CI/CD pipelines.
If you’ve ever lost an entire afternoon trying to figure out why a Gradle sync suddenly failed, or stared blankly at a cryptic Xcode build error that made zero sense, you know exactly what I mean. It wasn’t just complex; it was exhausting. Even tiny changes meant touching fragile native configuration files.
At some point, you stare at your screen and wonder: "Isn't there an easier way to do this?"
As Expo puts it: "Expo is a React Native framework with powerful cloud services to help you move faster at every stage of the app lifecycle."
The pitch is great: developers focus on JavaScript and React, and Expo handles the native nightmare. You get incredible speed of development, pre-bundled native APIs, and their absolute killer feature: Over-the-Air (OTA) updates.
Because a React Native app is essentially a JavaScript bundle running inside a native shell, OTA updates let you push bug fixes and UI tweaks straight to your users without waiting on a full store review for each one.
It's worth being precise here, because it's a common misconception: OTA isn't a loophole around the stores — both Apple and Google explicitly allow it. The catch is that an update only swaps the JavaScript bundle; the native binary stays exactly as it was reviewed. So you can ship bug fixes, performance improvements, copy changes and UI polish over the air. What you can't push is new native code, or — on iOS especially — changes that alter what the app fundamentally does (a new paywall, features that change its core purpose). Those still go through a normal submission.
But my early impressions of Expo were terrible. Historically, if a native feature wasn't already compiled into the Expo Go app, you were out of luck. Want to add a custom third-party library with native code? You couldn't. Need strict SSL pinning for a banking app? Impossible.
Overall, it felt like a highly restrictive environment. A locked box.
If you hit a wall, your only option was to run the dreaded expo eject command, a one-way ticket out of the managed workflow that unceremoniously dumped you back into the deep end of native configuration, usually breaking your project in the process.
I genuinely didn't understand the hype.
This is where Samuel comes back into the story.
At some point, he brought it up again: "You should really look into Expo… especially dev builds."
I gave him the classic developer nod. "Yeah, sure buddy," I said, before immediately going back to wrestling with my Podfile and entirely dismissing his advice.
A few months later, he tried again. "You're just being stubborn," he told me. "Expo is better now. You can actually do everything with it."
For the first time, I actually listened. I went home, did some proper research, and what I found completely blew my mind.
Around 2021, Expo introduced two features that fundamentally changed the game:
This wasn't "Bare vs Expo" anymore. This was native freedom plus Expo convenience.
You could start simple, avoid native complexity early on, and only introduce dev builds when your app actually requires them.
Once I actually made the switch, the day-to-day developer experience improvements were impossible to ignore.
(Note: Setup time today is closer to "medium" rather than "instant," but the trade-off is absolutely worth it).
Over the years, my perspective completely shifted. I stopped seeing Expo as a restrictive toy and realized it had evolved into a remarkably powerful platform.
For those who are as stubborn as I was, I’ll leave you with this:
The Expo of today is not the Expo you remember. You should seriously consider giving it another try.
And for those who haven't built with React Native yet, hopefully, this shows that getting started doesn't have to be a struggle.
Thanks for reading.



