When you write code in Expo you are writing React Native code. Expo has two main pieces:
Expo CLI (
expo-cli): a developer tool for creating projects, viewing logs, opening on your device, publishing, etc.Expo client: an app on your phone that lets you open your projects while you're working on them, without needing to go through XCode or Android Studio, and also lets other people view them too! And if you publish it through
expo-cli, people can access it at any time through the Expo client on Android or on iOS if signed in to the same account it was published with. Lastly, we also make it possible to build standalone apps so people don't have to use the Expo client to open it, and you can distribute to the app store and play store if you like.
So Expo is a set of tools built on top of React Native. These tools depend on one key belief held at Expo: it's possible to build most apps without ever needing to write native code, provided that you have a comprehensive set of APIs exposed to JavaScript.
This is important because with React Native you can always drop down to native code. This is incredibly helpful sometimes but it comes at a cost: you need to send people your binaries if you want them to test them, someone on the other side of the world can't just tap a link to open it while you're working on it and you can't just publish it with one click for someone to access it similar to how you would in a browser.
With Expo, we suggest that try to avoid dropping down to native code, if you can. As I mentioned above, we think that with a comprehensive set of APIs available to JavaScript, this shouldn't be necessary for most apps. So, we aim to provide this comprehensive set of APIs, and then build all of the awesome tooling that can exist in a world where the native runtime is shared.
However, if you must find that you want to drop down to native, you can use eject and continue using the native APIs that Expo gives you while having the same level of control as you would in any native project.
Read more about ejecting
Answer from brentvatne on Stack OverflowWhen you write code in Expo you are writing React Native code. Expo has two main pieces:
Expo CLI (
expo-cli): a developer tool for creating projects, viewing logs, opening on your device, publishing, etc.Expo client: an app on your phone that lets you open your projects while you're working on them, without needing to go through XCode or Android Studio, and also lets other people view them too! And if you publish it through
expo-cli, people can access it at any time through the Expo client on Android or on iOS if signed in to the same account it was published with. Lastly, we also make it possible to build standalone apps so people don't have to use the Expo client to open it, and you can distribute to the app store and play store if you like.
So Expo is a set of tools built on top of React Native. These tools depend on one key belief held at Expo: it's possible to build most apps without ever needing to write native code, provided that you have a comprehensive set of APIs exposed to JavaScript.
This is important because with React Native you can always drop down to native code. This is incredibly helpful sometimes but it comes at a cost: you need to send people your binaries if you want them to test them, someone on the other side of the world can't just tap a link to open it while you're working on it and you can't just publish it with one click for someone to access it similar to how you would in a browser.
With Expo, we suggest that try to avoid dropping down to native code, if you can. As I mentioned above, we think that with a comprehensive set of APIs available to JavaScript, this shouldn't be necessary for most apps. So, we aim to provide this comprehensive set of APIs, and then build all of the awesome tooling that can exist in a world where the native runtime is shared.
However, if you must find that you want to drop down to native, you can use eject and continue using the native APIs that Expo gives you while having the same level of control as you would in any native project.
Read more about ejecting
A summary of the documentation and answers from Expo employees:
React Native init:
Advantages
- You can add native modules written in Java or Objective-C (probably the only but the strongest one)
Disadvantages
- Needs Android Studio and Xcode to run the projects
- You can't develop for iOS without having a Mac
- Device has to be connected via USB to use it for testing
- Fonts need to be imported manually in Xcode
- If you want to share the app you need to send the whole
.apk/.ipafile - Does not provide JavaScript APIs out of the box, e.g., Push-Notifications, Asset Manager, they need to be manually installed and linked with npm for example
- Setting up a working project properly (including device configuration) is rather complicated and can take time
Expo
Advantages
- Setting up a project is easy and can be done in minutes
- You (and other people) can open the project while you're working on it
- Sharing the app is easy (via a QR code or link), you don't have to send the whole
.apkor.ipafile - No build necessary to run the app
- Integrates some basic libraries in a standard project (Push Notifications, Asset Manager, etc.)
- You can eject it to ExpoKit and integrate native code continuing using some of the Expo features, but not all of them
- Expo can build
.apkand.ipafiles (distribution to stores possible with Expo)
Disadvantages
- You can't add native modules (probably a game changer for some)
- You can't use libraries that use native code in Objective-C/Java
- The standard Hello World app is about 25MB big (because of the integrated libraries)
- If you want to use: FaceDetector, ARKit, or Payments you need to eject it to ExpoKit
- Ejecting it to ExpoKit has a trade-off of features of Expo, e.g. you cannot share via a QR code
- When ejecting to ExpoKit you are limited to the react-native version that is supported by ExpoKit then
- Debugging in ExpoKit (with native modules) is a lot more complicated, since it mixes two languages and different libraries (no official Expo support any more)
Sources:
- Detaching Expo Apps to ExpoKit: Concepts
- Difference between react-native-init and create-react-native-app #516
- Ejecting to ExpoKit
Videos
I am trying to develop an app and am not sure which to use. I know Expo is easier and quicker but you can't access native elements. But there should js lib to do most things. Or should I just start using CLI and if I use CLI would I still be able to write on code base and get an app that works for both ios and android?
Hi there, I had a question about what is the best way to create apps nowadays? I have noticed that a lot of people work with Expo, is the best option to create RN apps? Is recommended work with Expo always? What are the main differences
Thank you for you answers!!
I've used expo and cli - I enjoy the CLI personally for full on app development and use Expo specifically for quick prototyping. I've been a developer for about 7 years and only have been doing RN dev for about a year or so, so my opinion isn't expert by any means. That said, my main issue with Expo to build production level apps is its an additional layer that requires its own dependencies and configurations to work with certain RN libraries.
Been working on React Native for past 3 years, my personal preference is Expo. It's quick, efficient and gives less headaches. However, sometimes Expo faces issues related to package uncompatibility. If your app doesn't require such packages that are not compatible with Expo, then go ahead with Expo.
React Native CLI:
Advantages:
- You can add native modules written in Java/Objective-C, so you have full control of your application.
Disadvantages:
Needs Android Studio and XCode to run the projects
You can't develop for iOS without having a mac
If you want to share the app you need to send the whole
.apk/.ipafileDoes not provide JS APIs out of the box, e.g. Push-Notifications, Asset Manager, they need to be manually installed and linked with yarn for example.
Setting up a working project properly take more time.
Expo:
Advantages:
Setting up a project is easy and can be done in a few minutes.
Sharing the app is very easy (via QR-code or link).
No build necessary to run the app
Integrates some basic libraries in a standard project (Push Notifications, Asset Manager, etc.)
You can eject it to ExpoKit and integrate native code continuing using some of the Expo features, but not all of them
Expo can build
.apkand.ipafiles (distribution to stores possible with Expo)
Disadvantages:
You can't add native modules (probably a gamechanger for some)
You can't use libraries that use native code in Objective-C/Java (eg:
react-native-fbsdk)Large APK Size
Debugging in ExpoKit (with native modules) is a lot more complicated since it mixes two languages and different libraries.
Choosing between Expo and React Native CLI depends on your application requirements.
I prefer React Native CLI, expo has some good things but it has a lot of limitations and probably you will regret to use it in the future.
Check this website: https://apiko.com/blog/expo-vs-vanilla-react-native/
I was asked to setup a react native project for my company, which will be probably mantained for long and thus i have to do it properly. My question is: should i go for Expo or Cli? My answer would be CLI from what i understand now, since expo could lead to some limitations at some point and i don't want that to happen. On the other hand, Expo seems much simpler and many tutorials i see use it instead of CLI. What's your take?
Most of these comments are outdated. Expo managed with eas build and dev-client has all advantages of expo, including over the air updates and you can use any react-native just like with a bare workflow. It’s both the easiest way to get started but also the best way to manage a complex project with any react-native requirement and handle actually being in production with over the air updates.
It’s is no longer true that expo has any limitations compared to any other react-native setup.
Expo will provide you with a much faster workflow as they handle all the tiny differences between platforms as well as their newer service which allows app exports straight from the terminal.
Countering this, you are correct in assuming that Expo has it's limitations once you get further into development. There are a number of native libraries that don't support Expo and will require you to go into the bare workflow anyway.
For me, I've never needed a library that required me to forgo Expo. While starting a project without it will surely give you more control, I'm not sure it's control that a lot of people want to deal with or have the time to deal with (seriously, native code sucks)
Best of luck!
Edit: If you would like, you can always start a project in Expo to lay the foundation, then eject once you feel that you've got it under control
Currently in the middle of planning out a basic calendar app for my workplace where you can view upcoming events and see what's going on in the museum. I have my development environment up and running on my Intel Macbook Pro but I'm struggling to decide if I should use Expo or a bare React Native project.
What would you use in 2024 and why?