Based on my experience, I will tell you about the advantages and disadvantages of both variants.
Let’s get straight to the point.
Project start with Expo
Expo is a toolchain built around React Native to help you quickly start an app. It provides a set of tools that simplify the development and testing of React Native app and arms you with the components of users interface and services that are usually available in third-party native React Native components. With Expo you can find all of them in Expo SDK.
You can read how to set up your project in the Introduction section (Installation subsection)
- Fast and simple project installation (in just several minutes)
- A convenient utility Expo CLI that opens in a browser and helps to check the app status, devices it runs on, scan QR code or send the link via email to open the app in Expo client, switch the production / development mode and publish your app on Expo server.
- Expo client is an app that is installed from Google Play and Apple Store on your phone. It allows opening projects during development without build via XCode or Android Studio. With Expo client, you can send your app to others for review, which is very useful when testing as you can see all changes in code in Expo client without creating apk or ipa files.
- Expo SDK offers the collection of ready solutions, such as working with the device accelerometer, camera, notifications, geolocation, etc. You can see them in the section SDK API Reference. Expo team regularly updates SDK with new solutions.
- You can develop apps for ios without macOS with ios device and test them with Expo client
- Automatic management of certificates and app signatures
- You can’t add native modules written in Objective-C, Swift, Java, Kotlin
- You can’t use packages with native languages that require linking
- The app has a big size as it is built with all Expo SDK solutions, even those you don’t use. An application with Hello World weighs 25 MB
- Often everything works well in Expo client during testing, but certain problems may occur in a standalone app.
Why I don’t recommend using Expo at this time
Disadvantages, described above are not the entire story. Most of the problems occur at the end of a development process. I will describe some of the challenges our React Native team has faced.
If you detach, the part from Expo called ExpoKit will remain in your project. This is the collection of modules from Expo SDK where you can add native modules.
However, I don’t recommend to leave ExpoKit as it is difficult to debug together with the native code which causes a lot of problems. If you really want to use native modules, it’s better to give up on Expo and find alternative packages.
With ExpoKit you can’t share the project with QR code, build your app via Expo, and use Over the Air update. To turn on the notifications, you will need to connect a certificate.
- Dependence on Expo infrastructure
Often Expo servers were unavailable because of the overload and we had no chance to build an app. Sometimes notifications don’t work because of the problems with the server. Expo plans to get rid of this dependence in future updating, but it still remains for this moment.
- Dependence on a particular React Native version
In Expo you are tied to a particular React Native version they use at a moment. Often when there are some errors in React Native library, they fix them and issue a new update. Expo decides what React Native version to use and we can wait for several months to get the updates. The same about the bugs in Expo, that has releases usually once in one or several months.
On my opinion, Expo is the right choice if you need to develop an app without any specific features for which you have to link the packages.
The fact of the matter is that Expo actively strives to improve the functionality and has a lot of plans for the future. So we can assume that the situation may change for better. You can read about Expo objectives here
React Native without Expo
You can read about how to set up a project without Expo in React Native documentation in the section Getting Started (Building projects with Native code).
- You can add native modules written in Objective-C, Swift, Java, Kotlin, and packages that require linking
- You can decide by yourself what React Native version to use
- You won’t have an opportunity to develop iOS without macOS, as you have to use XCode for some of the settings.
- If you have started to work with React Native recently or have switched to it from Expo, setting a project will take a fair amount of time.
Why it's better to start your project with Vanilla React Native
- Native modules
The biggest advantage of React Native without Expo is that you can link the packages that use native modules and connect your native modules written in native languages. You also have an opportunity to and implement for example a background geolocation. You can add the package to compress images or videos and a lot of other packages that will improve your application.
You can choose that React Native version to use, update to the newer versions, and get new opportunities. Besides, you can fork the code base and add your improvements (the way Airbnb and Microsoft does).
- React Native Fabric architecture
This is another reason why I recommend to use React Native without Expo. You can learn more about it in this video.
As Expo decides what React Native version to use, it often takes a lot of time to issue the updates. I guess that when React Native will issue a new version with new architecture, Expo will not update RN version any time soon.
- OTA alternative
What I really like in Expo is Over the Air (OTA) feature - update over the air without additional deployment on Google Play or Apple Store.
I have found a better alternative for this - a service called CodePush (it has even more opportunities and settings). For work with notifications use the library Onesignal, that also gives more capabilities that notifications available in Expo.
Should I start my project with or without Expo?
In this case, there is no one size fits all. It all depends on the requirements and functionality you want to implement in your app. In this article,I have provided the main disadvantages of Expo. If this is not a big issue for you, then Expo may be the right choice.
However, if your app requires a specific functionality and packages with native modules (written with native languages), it’s better to go with Vanilla React Native. As for me, the only drawback is that without Expo the project setup will take more time, but if you understand how the packages linking works and how to set up an app via Android Studio and XCode, you will easily develop React Native project without Expo.