Learn the difference between React Native Expo and React Native CLI
There are two main tools you can use to develop React Native apps. Either you can use the official React Native CLI by Facebook or the React Native Expo CLI.
CLI stands for Command Line Interface. A CLI is a tool that you use to communicate with your computer, like giving it commands or retrieving data.
The difference between React Native CLI and Expo is:
- React Native CLI gives you total freedom and control over how you build your app. The price is that you have to more work to get things done. More freedom means more management. You won’t get much out of the box or much hand-holding with this tool.
- React Native Expo CLI gives you many presets out of the box. A lot of commonly used UI components are already made for you. This makes it faster to bootstrap a new React Native app. The downside is that you have less freedom to build your app your way.
Another key difference is that with the React Native CLI you have the ability to write native code in either Java or Objective-C/Swift to address platform-specific issues, e.g. native camera functionality that could be different on Android and iOS respectively. With Expo you have no option of writing true native code, which for some types of apps is a dealbreaker.
React Native CLI takes a configuration over convention approach, while React Native Expo takes a convention over configuration approach.
A good analogy is to compare Angular vs. React.
Angular is an MVC framework that forces you to adopt a set of rules to build your application (the Angular way). E.g. you have to use TypeScript if you build Angular Apps. You also can’t just break out of an Angular app, because by using Angular, your app becomes an Angular app. This is kinda how the Expo CLI is.
MVC stands for Model View Controller.
React is a library that primarily handles the View part of the MVC while leaving the rest up to you. There are still some React conventions you should follow, but a lot of the configuration of a React app is up to you. E.g. using TypeScript is optional in React. This is kinda how the React Native CLI is. You have more freedom, less enforced structure.
The advantage of using frameworks/tools that enforce rules is that you as a developer won’t have to make as many decisions. It’s also convenient that you know that the community is following the same set of rules, which means that code documentation and support will be more consistent.
The downside is when you need to break the rules, and you might not be able to or have to work hard to do it. You should make decisions based on context. Assess the requirements of your app, then make a decision.
If you have already written down exactly the type of features that your app needs and the pre-existing Expo component library already has everything you need, then it makes sense to use Expo, to save time and money.
If, however, you’re like me, and working on an app that either has a handful of features that Expo don’t provide — or there’s uncertainty about the requirements of your future features, well then React Native CLI makes sense.
What about this “Ejecting an Expo app” I keep hearing about?
You might have heard that you can start your React Native app as an Expo app and then eject it (break out of it) later and switch to the React Native CLI if you should need more fine-grained control. That’s an option.
On paper ejecting an Expo app sounds great, but several developers have warned me about betting my money on this “ejection process” being a pain-free journey.
I guess it depends on the complexity of your app. You also shouldn’t count out the importance of being a little lucky. Sometimes a single module update can raise seemingly unexplainable havoc in your app, such as causing your build process to fail.