React Native, the sweet, sweet siren song that lures web developers into the world of mobile app development. "Learn once, write everywhere," they said. "It'll be fun," they said. And for a hot minute in 2016, it really did feel like the future.
But now? In 2025? Unless you're using Expo, bare React Native development feels like trying to assemble IKEA furniture blindfolded while someone throws random Xcode build errors at your face. Let’s talk about why building apps in bare React Native is, quite frankly, a flaming dumpster fire of pain, frustration, and existential dread.
1. Welcome to Dependency Hell 🔥
Every time you run npm install
, a small puppy cries somewhere. Why? Because the dependencies never align. Ever.
npm install react-native-ble-plx
Great! Now you’ve got Bluetooth. Except, wait—your app crashes on Android 14 and won’t even build on iOS. Now you need to patch a patch for a patch:
patch-package
You’re not a mobile dev anymore. You’re a digital janitor duct-taping together incompatible packages, praying the gods of semver show mercy.
Expo fix:
expo install expo-bluetooth
That’s it. It just works. Life is beautiful again.
2. The iOS Dev Experience: An Xcode Horror Story 👻
Want to build for iOS? Great! Fire up Xcode. Wait 20 minutes. Oh look, a build error that says:
Undefined symbol: ___llvm_profile_runtime
WHAT DOES THAT EVEN MEAN?
You’ll be diving deep into .xcworkspace
, fiddling with "Build Phases" like you’re defusing a bomb. You Google for 45 minutes, find a StackOverflow post from 2018 that no longer applies, and cry.
Expo fix:
expo run:ios
Or even better:
npx expo start --dev-client
No Xcode. No tears. Just vibes.
3. Android Builds: Now With Extra Confusion 🍵
Android in bare RN is like assembling a 1,000-piece puzzle with no picture. Want to use react-native-video
?
implementation 'com.google.android.exoplayer:exoplayer:2.18.1'
Oops! Your Gradle version doesn’t match. Now you're updating build.gradle
, gradle.properties
, gradle-wrapper.properties
, and sacrificing a goat to Gradle Godzilla.
Expo fix: Already integrated. Already compatible. Already peace of mind. You can use expo-av
and move on with your life.
4. CocoaPods. Just... CocoaPods 😭
cd ios && pod install
And then...
[!] CocoaPods could not find compatible versions for pod "Firebase/Core":
Your app doesn't build. Again. You delete Podfile.lock
, reinstall, restart, reboot, re-evaluate your life choices.
Expo fix: No CocoaPods. Or if you're in custom dev client, it’s all handled for you. Expo even tells you when you're being dumb. Love that.
5. Linking Native Modules: The Nightmare Fuel 🔗
You try to use some cool native module. But now you have to link it.
react-native link react-native-camera
But wait—it only works on RN 0.62 and you're on 0.71. So now you're manually editing MainApplication.java
, hoping you don’t break everything.
Expo fix: Most popular modules are preconfigured. And if you're using expo-dev-client
, you can still use custom native code while keeping your sanity.
6. OTA Updates? Not Without Tears 📦
In bare React Native, deploying over-the-air updates means integrating CodePush or rolling your own system. Hope you like YAML and pain!
Expo fix:
npx expo export --experimental-bundle
And boom, OTA update is ready. You can even do it from your phone while eating ramen.
7. Permissions. Or Why Your App Crashes on First Launch 🙃
You forgot to add this to your AndroidManifest.xml
:
<uses-permission android:name="android.permission.CAMERA" />
And this to Info.plist
:
<key>NSCameraUsageDescription</key>
<string>We need your camera because reasons</string>
Boom. Crash. Rage.
Expo fix:
import * as Permissions from 'expo-permissions';
Done. Expo even prompts the user automatically like a responsible digital citizen.
8. Debugging: The Purgatory of Logs 📉
Metro bundler crashes. You Google. Someone says "clear the cache."
watchman watch-del-all && rm -rf node_modules && npm install
Still broken. You scream into the void.
Expo fix:
You get beautiful errors. Red screen of death with readable messages. Plus expo-dev-tools
is actually helpful.
Conclusion: Bare React Native is a Masochist’s Playground 🧨
There was a time when React Native felt lightweight, full of promise. But now? Without Expo, it’s like trying to run a modern app on a Nokia 3310.
Expo is React Native, but evolved. It’s the Charizard to bare RN’s Charmander. You want OTA updates, smoother builds, easier native integration, and a good night’s sleep? Use Expo. Especially with expo-dev-client
, you get the flexibility of bare RN with the magic of Expo.
Unless you're building something wild with tons of custom native modules that only 3 people on Earth know how to compile... just use Expo.
Your dev life will thank you. Your mental health will thank you. Your build times will go from “coffee break” to “oh it's already done?”
In 2025, bare React Native isn’t brave. It’s barbaric.
Stay safe out there.
Bonus Meme:
Me: tries to build a bare React Native app
React Native:
"You have chosen the path of pain."
TL;DR:
Pain Point | Bare RN | Expo |
---|---|---|
Dependencies | ⚠️💣 | ✅ Smooth AF |
iOS Builds | 😱 | 🍎 1-liner magic |
Android Config | 🤯 | ✅ No Gradle tears |
CocoaPods | 🧨 | 🚫 Mostly avoidable |
Native Linking | 🧟♂️ | 🧘 Pre-configured |
OTA Updates | 🛠️ | ⚡ Built-in |
Permissions | 🧾 Manual | ✅ Handled nicely |
Debugging | 🧙♂️ Arcane Logs | 🪄 Helpful UI |
Use Expo. Be happy. Or don’t—and start drinking.
Top comments (0)