This month I started a mobile app project. Why? I'm a Web developer since 2006 and avoided getting involved in this whole "native app development" thing like the plague. I went to university from 2007 - 2011 the time where iPhones and Android got out, and most of my fellow student got into mobile while or after their studies.
They made good money, but to me it sounded horrible!
Objective-C? Who uses this?!
Java? This was the bane of my studies!
Also, the big money seemed to be exclusively in iOS apps and I hated Apple from the bottom of my heart.
So, how did I get into this mess?
I did React for two years and had the idea that doing apps with React Native couldn't be much different, so I got me a RN project in which I'm in for a month now. Now I will tell you about what I learned.
React Native iOS apps without a Mac
It is possible. There is the Expo project for example, that lets you build on their servers and you only have to write JavaScript in your apps. They give you a client, which is basically a RN runtime. It's in play store and app store, so you simply get yourself an iPhone, install the Expo client, scan a QR-code and run your app.
A slimmer version of this process exists in the form of create-react-native-app, which basically builds on Expo, but doesn't require an Expo account to get started.
Also, Expo lets you run the app in its client over the Internet via Proxies and such, CRNA only works in your local network.
What's the catch? There is always a catch!
You can only use native modules that are included in RN and Expo, but at least Expo brings you a bunch of useful extra components like Video, Audio, Notifications and GL, so probably 80% of all apps will get along with this. You can install all JavaScript modules you like, just no native ones.
What React Native does and what it doesn't
When I started the whole thing, I thought RN would be a complete developing experience, but well, I was wrong. RN helps you developing and enables you to use your JavaScript and React skills for native apps, but it won't help you to get your app in the app store. It won't even help you to get it on all the devices of your beta testers.
If you use CRNA or Expo, you get to run your app in the Expo client on any iPhone. Expo even gives you a build service, that spits out IPAs you can get into the app store, but if you don't want to rely on Expos services OR you need other native modules Expo doesn't deliver, you will probably need to build your apps on your own.
If you develop with plain RN on a Mac, you get to run your app in the Simulator or on a USB connected device, but RN will stop at the border where your app is just a regular Xcode project.
So you did your dev and now you want to build your IPA to deliver it to the test devices of your co-workers.
React Native won't sign your code, package your app or create a provisioning profile for you. These are all Apple concepts and have nothing to do with RN.
But luckily there are other tools that do exactly this for you.
I found Fastlane, which does all the heavy lifting. It has really nice error messages and covers all the things you need to do after you coded your app and tested it on your own devices. It even seems to know about RN and gives some tips on where to run fastlane init
or fastlane match init
and the best is, it runs completely in the shell, so you can integrate it nicely in your package.json
and run npm run build:ios:beta
and be done with it. No more looking into Xcode.
Problems with Create React Native App
I used CRNA to get started, it had most features I needed and it was really easy to set things up. After 5 minutes I could write my business logic in JavaScript and all was good.
To get an IPA out of it that was signed correctly, I needed to use the Expo build service, which required an Expo account. If you don't want this, you need to eject from your CRNA project into a plain RN project and build it yourself on a Mac.
Ejecting was a bit harder than I thought, especially if you do it because you want to build things yourself.
There are two options, either the ExpoKit or the regular RN eject.
The ExpoKit option still requires you to build with the Expo service, so it wasn't an option.
The RN one didn't let me keep the Expo modules I was using. This wasn't too bad, since a few of these packages were just wrappers for regular native RN modules and I found replacements for everything else. The only thing that bit me were the vector-icons
. I used them all over the place, but CRNA didn't tell me they wouldn't work anymore. So everything blew up after eject. I got it fixed rather fast tho, the Expo module was just a wrapper and I could use the regular react-native-vector-icons
module.
Also, it seemed that the eject didn't set all values in the .plist
file correctly. I had a app.ios.js
that was registering a different name than my app was called, so Xcode couldn't find it, but I found the Xcode errors good enough to fix these issues.
When to use what?
When I did this, I had the feeling that this whole React Native thing has different levels and depending on what you need, you don't have to go all-in.
Prototyping
Create React Native App is probably enough. You get all the React Native and Expo components and APIs and will create an app you can show your co-workers or customers really fast.
You even get the possibility to eject and use most of your code. You just have to replace the Expo Components and APIs with something different then, if you don't want to use ExpoKit, which requires to use the Expo build service.
No Mac for development
Expo is the way to go, you get all the features of CRNA and a build service to package your creations. It requires a (free) Expo account. Also you only can use the included native APIs and Components.
You can detach, which is the Expo version of CRNAs eject and do regular RN development from then.
Need other native APIs and/or Components
You can use CRNA and eject right after react-native init
so you get a nice project structure and end up with a normal React Native project. Then you can use native modules of your liking.
For most native APIs (probably all?) there are already so called React Native bridges that you can install via npm and include in your project via linking, so you don't have to write Objective-C or Swift yourself.
You will need to set up your own build tooling tho, but Fastlane is really nice and helps you with all steps.
Top comments (17)
Thank you so much for sharing your experience, it has been life-changing from the point of view that your hard-won insights will probably save my partner and I tens of hours of learning and development time. I just started with CRNA two days ago and your piece has provided a much needed course correction.
Makes me really happy to read this :)
This experience report is super useful, thanks so much! Sorry you ran into problems with ejecting and CRNA, I created a GitHub issue for the vector icons issue. The code for setting up the plists in the eject process comes from the
react-native-cli
tool that's part of RN, but I'd be very happy to file an issue upstream and try to resolve it if you have more details about what exactly was broken when creating the iOS project.Totally agree that fastlane is awesome, a lot of our build service is powered by those tools.
what is the difference between CRNA and Expo? which one should I use?
CRNA uses Expo under the hood, but it's faster to get started with, doesn't need a user account, and doesn't rely on any of Expo's backend services.
Thank you so much for sharing your experience.
I started to learn React native yesterday. CRNA and Building project from native code made me confusing where to go.
Now it's clear for me where to go and how to go.
Thanks again.
You are welcome :)
Hi, nice article you have written, kudos.
Have you written about beta testing and automation react native apps, that would be awesome.
I didn't test with many users at the moment so I don't need automation.
Currently I'm createing two apps, both iOS, and just distribute them via Expo or OTA (stackoverflow.com/questions/235613...)
I got into React Native early on and then moved on to some other stuff. It's great to see how far the tooling and bridges have come since early on.
They are far from perfect, but I found all I needed and got working rather fast. At the moment I'm happy, but I'll wait praising RN till I got the app in the store and happy customers :D
I really think React Native has the right idea and I'd definitely bet on it. Unless something comes along that's way better, RN should win the tooling game soon enough. Too many benefits of the web-dev style of working.
Aspiring developer. Good info to know prior to putting in work.
Some day's ago I tried CRNA and afterward, I tried to build my CRNA project with Expo it gives me a big size of APK which is for android. I felt really bad for that... it's immature just.
Yes, it's rather big, but I read that the file created is much bigger than the file the users download from the app/play store later.
happy to see this after 2 days starting RN and struggling with Expo & Eject. Lovely.
Hehe, yes it's a struggle.
I try to avoid ejecting as long as possible and since Expo gets new native module every release it's getting easier :)