When it comes to developing mobile applications using React Native, we have two options: React Native CLI or Expo. For years, We’ve been building and shipping mobile apps using React Native CLI for our projects. While it’s powerful, we’ve found that it comes with its challenges, such as:
- App build, deployment, and submission
- Code-signing and certificate management
- Version upgrades
- Third-party library dependency management
- TypeScript integration
Recently, I decided to try Expo and was blown away by how much easier it made the development process. In this blog post, I’ll share my thoughts on Expo with the streamlined and simple development experience it provides.
As per the React Native docs,
Expo is a set of tools and services built around React Native and, while it has many features, the most relevant feature for us right now is that it can get you writing a React Native app within minutes.
One of the benefits of using Expo is the speed at which we can start and run a new project. With Expo, we can create a new project with just one command and are ready to start developing immediately. React Native CLI, however, requires us to manually set up our development environment, which can be daunting and time-consuming. A few hurdles that often frustrate a new developer are:
- Installing Xcode, which is a large download taking up a lot of space
- Installing Java and finding the correct JDK versions for Android
- Installing the Android SDK and configuring the right installation paths
Fortunately, Expo offers an alternative approach that abstracts away these problems allowing us to focus on building the app instead.
Expo provides a comprehensive set of pre-built components and APIs that cover many commonly used mobile features, such as Camera, Image, MapView, Push notifications, Async storage, File system, etc. These components and APIs are easy to use, well-documented, and can be easily integrated into the project. The Expo documentation is also well-organized and searchable, making it easy to find the information and examples needed to develop specific features in an app.
React Native CLI, on the other hand, doesn’t provide these pre-built components out of the box, which means we have to build them ourselves or rely on third-party libraries. Developers often need to spend time searching for third-party libraries or working out how to implement certain features from scratch.
In short, Expo’s pre-built components and APIs, combined with its well-organized and searchable documentation, make it easier for developers to build high-quality mobile app features saving time and effort in the development process.
Based on my personal experience as a React Native developer for years, the majority of app development projects do not require Native modules. This is because most apps are built using standard libraries and UI components already available in the React Native ecosystem.
However, for years, Expo lacked this Native module support, which is one of the reasons developers did not choose Expo for mobile projects. With the Expo modules API, this changed, and talking to native iOS or Android became much simpler. This means that developers can take advantage of the benefits of Expo while still being able to access native functionality when needed.
During interviews, one of my favourite questions is about upgrading React Native versions. As upgrading is a complex process, it tempts me to probe further when candidates claim it to be easy. With React Native CLI, upgrades can be time-consuming and challenging, especially if we’re unfamiliar with the underlying native platform code. We have to perform the upgrades incrementally, with sometimes multiple breaking changes and platform compatibility issues to deal with. This can be a significant hurdle for some developers.
One of the biggest advantages of Expo is that upgrades are easier than React Native CLI. The Expo team works towards abstracting the native iOS and Android complexities so that developers don’t need to worry about updating native code when they upgrade React Native. Upgrading Expo versions is not a one-command exercise but is simpler and more predictable than upgrading a React Native CLI project. Expo’s clear and detailed upgrade guides ensure that developers have a smooth upgrade process by following the changes to be made in the code and configuration.
Example: “Upgrading your app” section in Expo SDK 48
Expo comes with a client app called Expo Go, which allows developers to view and test the development app on a physical device without having to go through the App Store or Google Play. But the real power of Expo Go lies in its ability to create better collaboration between developers and team members such as testers or product owners. Developers can share their development server with testers, allowing them to instantly see the changes made to the app, thus improving the feedback loop. This ultimately results in a more streamlined development process and a better end product.
React Native CLI, on the other hand, requires us to set up our testing environment manually, and apps cannot be tested on actual devices without uploading the builds to the App Store or Google Play.
If we want to collaborate with the world, Expo makes it possible using Expo Snack. Expo Snack is an excellent tool for sharing runnable code snippets and inviting feedback from others. It’s easier to share a link to our code and get a second opinion on a problem.
Public Snacks can be found here.
Expo Application Services or EAS is a service that makes it easier to build, test, and publish apps built using Expo. With EAS, we can build and ship apps to a real device in minutes without having to set up complicated build systems. EAS also provides an automated app submission process that makes submitting the app to the iOS App Store and Google Play Store easier. With EAS, developers can define multiple environments (dev, staging, and production) with different configuration values. EAS also automatically manages the App release version and build numbers for both platforms.
This is otherwise hard with React Native CLI. Automating it using a tool like FastLane is difficult and time-consuming. With Expo, developers can focus on building the app rather than worrying about the intricacies of the app build and submission process.
Expo also provides EAS updates that implement an over-the-air (OTA) app update solution without submitting an App build to the iOS and Android app stores. This is similar to Microsoft’s React Native CodePush but is available out of the box while using EAS. This means that developers can easily update the app without having to go through the submission process, making it faster to iterate, address issues, and improve our app over time.
While EAS offers a free plan that allows teams to use all the above features on their Expo apps, there are some limitations to the free plan. Users may experience longer wait times for their builds to complete during periods of high demand. To address this, users can choose to upgrade to the paid plan that offers a priority queue for faster app builds, among other features.
While this post might make it seem like Expo is better than React Native CLI, it’s important to note that Expo is not a separate framework from React Native. Rather, it’s built on top of React Native and is dependent on the innovation and improvements made by the React Native community. Therefore, it’s not a comparison but rather an explanation of the additional benefits that Expo offers.
Overall, Expo should be the default choice for most mobile projects. If you’re starting with React Native, we highly recommend trying out Expo to make your development journey smoother and more productive. If you’re interested in learning more about thoughtbot or how we work with React Native, check out our work.