How to start a project in React Native - Expo or React Native CLI?
React Native is a popular JavaScript framework created by Facebook that allows you to create native mobile apps for Android and iOS using the React library. Before you start your first project, you need to choose the right starting tool. With React Native, you have two main approaches: Expo and React Native CLI. Choosing between the two is crucial for your development experience and workflow, so it's worth getting to know their specifics.

- 1. Expo – definition and use
- 2. Advantages of Expo:
- 3. Disadvantages of Expo
- 4. React Native CLI – definition and use
- 4.1. Advantages of React Native CLI:
- 4.2. Disadvantages of React Native CLI:
- 5. Comparison of Expo and React Native CLI
- 6. Practical Expo installation
- 7. React Native CLI installation
- 7.1. Steps to set up and run a React Native CLI project:
- 8. Which solution should I choose?
- 8.1. For beginners
- 8.2. For intermediate users
- 8.3. For advanced users
- 9. Summary
Expo – definition and use
Expo is an open-source platform and framework based on React Native, designed to simplify the creation of mobile applications. You can think of it as the web equivalent of Create React App, but for mobile applications. Expo builds the basic structure of the project for you, so you don’t have to dive straight into native configurations. Expo provides a so-called managed workflow, where many aspects of native configuration are handled automatically by Expo tools.
In practice, Expo consists of several elements. The main one is Expo CLI – a command line tool that you use to create and manage an Expo project. Another important element is Expo Go – a mobile application available on Google Play and the App Store that allows you to run and test the application you are creating without the need to build a native APK/IPA file. All you have to do is scan the QR code generated by Expo CLI to see your application on your phone in seconds. Expo also offers services such as EAS (Expo Application Services), including EAS Build for building applications in the cloud and EAS Update for deploying updates over-the-air.
Advantages of Expo:
- Low entry threshold – Expo is beginner-friendly and allows you to start working with React Native quickly.
- Simple configuration – you don’t need to install Android Studio or Xcode to create an application. All you need is Node.js and Expo CLI.
- A wide range of ready-made modules (Expo SDK) – you have immediate access to APIs such as camera, push notifications, location, accelerometer and others.
- Rapid prototyping – you can focus on writing JavaScript/React code instead of complicated native configuration.
- Easy testing on devices – you can launch the application in no time thanks to Expo Go, without the need to build APK/IPA files.
- Automatic refresh (Fast Refresh) – changes in the code are immediately visible on the phone/emulator, which speeds up development.
- Support for OTA updates – thanks to Expo, you can update the application over-the-air without having to republish it in the stores.
Disadvantages of Expo
- Limited access to native modules – you do not have full control over native code in a managed workflow. Some libraries are not available in the standard Expo SDK.
- No support for all native libraries – if your application requires specific native libraries that are not integrated with Expo, you may encounter difficulties.
- Less flexibility – Expo has introduced config plugins and development builds, but using them involves additional configuration steps, and in some cases it may be necessary to switch to a bare workflow.
- Larger app size – apps built in Expo tend to be larger than the same apps built in pure React Native because they contain code for unused Expo modules.
- Potential impact on performance – a heavier app can result in slightly worse performance on older devices.
- Different process of building a production app – you cannot use standard commands such as
gradlew assembleReleaseorXcode Archive. Expo requires the use of the EAS Build service. - Costs of EAS Build – the free version allows a limited number of builds per month. The paid version can generate additional costs (from ~$1 to $4 per single build).
- Local building requires additional steps – you can build the application locally (
eas build --local), but then you lose some of the simplifications offered by Expo and the configuration becomes more similar to React Native CLI.
React Native CLI – definition and use
React Native CLI is a traditional approach to React Native app development, using the React Native command line (react-native) and manual configuration of the native environment. It is often referred to as a bare workflow to distinguish it from the Expo-managed workflow. When you initialize a project with the React Native CLI, you get a complete native Xcode project for iOS and an Android project (Gradle) for Android. This gives you full control over the native code of your app – you can modify the configuration of the native project, add your own Objective-C/Swift or Java/Kotlin files, and install any native libraries. In other words, the React Native CLI does not abstract the native layer from you, which on the one hand ensures maximum flexibility, and on the other hand requires more knowledge and work during configuration.
Advantages of React Native CLI:
- Full control over native code – you can modify Android and iOS files without the limitations imposed by Expo.
- No restrictions on the use of native libraries – you can use any native modules libraries, even those that are not supported by Expo SDK.
- Ability to create your own native modules – if standard solutions are not enough, you can write code in Java/Kotlin (Android) or Objective-C/Swift (iOS).
- Better performance optimization – you have access to advanced build settings, e.g. Gradle and Xcode, which allows for better application optimization.
- Smaller app size – only the code and libraries that are actually used end up in the project, resulting in smaller installation files and better performance.
- Flexibility in app building – you can manually control the compilation processes (
gradlew assembleRelease,Xcode Archive) without having to use cloud services. - Easier integration with existing native apps – if you want to add React Native to an existing iOS/Android app, the CLI gives you complete freedom in integration.
- Popularity in the business environment – large production applications are more likely to choose React Native CLI because it allows the project to be customized to meet non-standard customer requirements.
Disadvantages of React Native CLI:
- Complex initial setup – requires manual installation and configuration of the environment, including: Node.js, JDK (Java Development Kit) for Android, Android Studio (including Android SDK and emulators), Xcode (on macOS) and CocoaPods to handle iOS dependencies.
- Long setup time – compared to Expo, the first project launch can take much longer, especially if the environment has not been configured before.
- High learning curve – requires knowledge of Android/iOS basics, which can be challenging for novice developers.
- Hardware requirements – a Mac is required to develop iOS apps, and Android emulators may require powerful hardware.
- Debugging issues – in case of errors, Gradle (Android) or Xcode (iOS) logs often need to be analyzed, which requires additional technical knowledge.
- Manual configuration of native libraries – some libraries require you to manually add API keys, link dependencies or edit configuration files.
- Longer startup time for a new application – you have to go through several additional configuration steps before you can see the first results of your work.
- No ready-made solution for OTA updates – unlike Expo, which allows for easy implementation of over-the-airupdates, here you have to take care of this process yourself.
- Dependence on native compilation processes – compiling a project can be time-consuming and prone to problems resulting from Android Studio or Xcode updates.
Despite these difficulties, React Native CLI is irreplaceable when you need full control and scalability. Most large production applications are created in this mode – it ensures that you will not encounter limitations as the project grows and allows integration with native projects (e.g. joining React Native to an existing native application).
See also: React Native vs Flutter.
Comparison of Expo and React Native CLI
Below, we present a comparison of the most important aspects of both approaches:
| Aspect | Expo | React Native CLI |
|---|
| Easy installation | Very high – only requires Node.js and the installation of Expo CLI. Get started quickly in a few minutes. Android Studio/Xcode are not required to get started. | Lower – requires installation and configuration of Android Studio (Android SDK, emulator) and on macOS also Xcode (iOS SDK). If you have no experience, the configuration can take ~1h. |
| Access to native modules | Limited to modules supported by Expo SDK. It is not possible to add your own native code without leaving the managed workflow (you must use the development build or eject). This can be a barrier to more complex projects. | Full access – you can use any of the libraries and write your own native code. React Native CLI allows you to integrate any modules and platform-specific functions (camera, Bluetooth, payments, etc.) without imposed limitations. |
| App size (APK/IPA) | Usually larger – the default Expo build contains many modules, even if not all of them are used, which increases the weight of the application. This can result in slower startup on weaker devices. (Note: new Expo versions improve this aspect by excluding unused code during build). | Usually smaller – only what you consciously add ends up in the application. No overhead from unused Expo libraries. You can remove unnecessary dependencies and thus optimize the size and performance of the application. |
| Support for production applications | Yes, but with some reservations. Expo is great for prototypes and less complex applications. For larger production applications, it is often necessary to use EAS Build to create the final files for iOS/Android. Large companies use Expo less frequently, unless it fits their requirements – if necessary, you can still “eject” from Expo to bare workflow. | Yes, React Native CLI is the standard approach for production applications. It is used by companies that want to have full control and optimization. Projects created with CLI are easier to integrate with existing native applications and continuous integrations (CI/CD). In the long term, CLI is suitable for complex, commercial projects. |
Practical Expo installation
Let’s get down to business – below you will find instructions on how to install Expo and create and run a new React Native project with Expo.
Steps to install and run an Expo project:
1. Install Node.js – if you don’t have it yet, download the latest LTS version of Node.js from nodejs.org and install it. Expo requires Node.js to run its CLI.
2. Install Expo CLI – the best way is to use npx to run the create-expo-apptool, which will create an Expo project. In the terminal, run the command:
npx create-expo-app@latest AwesomeProject
The above command will create a new Expo project called “AwesomeProject” with default settings. Alternatively, you can install Expo CLI globally with the command npm install -g expo-cli and then use expo init AwesomeProject – the result will be similar. During initialization, Expo will ask you a few questions, including choosing a project template.
3. Select a template – Expo provides various starter templates. The most common choices are: blank (a clean project with one screen) and tabs (a project with a ready-made tab-bar navigation and several example screens). If you are just starting out, choose blank template – you will get a minimal React Native application. The “Tabs” template already includes the React Navigation library and sample screens with a tab menu. You can also see the workflow option: managed (default) or bare. Make sure that the Managed workflow mode (i.e. standard Expo) is selected to be able to use all Expo facilities.
4. Install dependencies and start the project – once the project has been successfully created, go to the project folder and start the development server:
cd AwesomeProject
npm start # lub: expo start
You should see the Metro Bundler package running in the console and a message saying that the application is ready to connect. A QR code will also appear.
5. Run the application on your device or emulator – now you can preview how the application works:
- On a physical device: Install the Expo Go application from the store (Google Play or App Store) on your phone. Make sure that your phone and computer are connected to the same Wi-Fi network. Scan the QR code displayed on the Expo terminal/window with your phone camera – the Expo Go app will connect to your developer server and launch the app. Any saved changes to the code will automatically refresh the preview on your phone.
- On an emulator/simulator: If you have an Android emulator (AVD) or an iOS simulator installed, make sure it is running. In the terminal window with Metro Bundler, press the
akey to open the app on Android Emulator, orito open on iOS Simulator (on macOS)
Expo CLI will automatically build a debug version and send it to the emulator. After a while, you should see the React Native splash screen (by default, this is the screen that says “Welcome to React Native…”).
6. Modification and hot-reload: Now you can open the App.js file in the editor, make changes (e.g. change the welcome text) and save. Expo will immediately reload the app on the device/emulator, showing the changes you made thanks to the Fast Refresh mechanism that is enabled by default.
Congratulations! Your Expo project is up and running. The whole process – from installation to seeing the app – is very fast and beginner-friendly. For more details, check out the official Expo documentation.
React Native CLI installation
The React Native CLI approach is a little more time-consuming to set up. It requires you to install several tools and native dependencies, but it will allow you to build your app from scratch on your own computer. Instructions are below:
Steps to set up and run a React Native CLI project:
1. Prepare the environment:
- Node.js: Install Node.js (if you don’t have it already) – as with Expo, Node is required to manage JavaScript packages and run Metro Bundler.
- JDK (Java Development Kit): Download and install JDK version 11 or higher (React Native currently recommends JDK 11 LTS). On Windows/Mac, make sure that the
JAVA_HOMEenvironment variable points to the JDK installation directory. - Android Studio (Android SDK): Install Android Studio – during installation, select the option to install the latest Android SDK and the AVD (Android Virtual Device) configurator, as you will need them to emulate the application on Android. After installing Android Studio, launch it once and go through the “SDK Manager” configurator to install Android platforms (e.g. Android 13/API 33) and the “AVD Manager” to create a virtual device (e.g. Pixel 5 with Android). Additionally, add the path to the Android SDK tools (
platform-tools) to thePATHvariableto be able to use the adb commands in the terminal. - Xcode (macOS only, for iOS): If you are using a Mac and plan to develop iOS apps, install the latest Xcode from the Mac App Store. After installation, open Xcode and install additional tools (you may be prompted to install command line tools). Also install the CocoaPods tool (
sudo gem install cocoapodsin Terminal), which you will need to manage iOS libraries. Note: on Windows/Linux, it is not possible to build or run a native iOS application – macOS is required for this. - React Native CLI: You don’t need to install anything separately – React Native has a built-in CLI tool. We will use it through
npx, which will always launch the latest version of the CLI.
2. Create a new React Native project: Once you have configured the above, you can create a project. Use the following command in Terminal/Powershell:
npx react-native init MyProject
where “MyProject” is the name of your app. This command will generate a directory structure with a sample app (containing the App.js component with a simple splash screen). With npx you always use the current version of the React Native CLI – there is no need to install the global react-native-clipackage. After a few minutes (depending on the speed of your internet connection and computer), the project will be created.
3. Run Metro Bundler: Go to the project folder: cd MyProject. Then (preferably in a separate terminal window) run the Metro server:
npx react-native start
Metro Bundler is a server that will be responsible for delivering the JavaScript package to your application. It should start on the default port 8081 and listen for code changes.
(Note: Many commands, such as run-android/run-ios, automatically start Metro, so you can skip this step – however, it is recommended to have a separate window with Metro to follow any JavaScript error logs).
4. Run the Android app: Make sure you have the Android emulator (AVD) running or a physical phone connected with USB debugging enabled. Then, in the project’s main directory, execute the command:
npx react-native run-android
This will build the Android application and install it on the emulator/device. The first time it is run, Gradle will download all the necessary dependencies, which may take a few minutes. If everything is configured correctly, after compilation you will see the MyProject application screen on the emulator (as in Expo, by default it is the React Native welcome screen)
If there are any errors, check the console messages – the most common problems are that the emulator is not running or that the SDK licenses have not been accepted (if necessary, run Android Studio, which will tell you how to accept the licenses). After a successful launch, Metro Bundler will start transferring the JavaScript code to the app.
5. Run the app on iOS (macOS): If you are working on a Mac, you can run the app on the iOS Simulator. Make sure you have the simulator open (e.g. iPhone 14). In the project directory, do the following:
npx react-native run-ios
This command will open the iOS project in Xcode, build it and run it in the simulator. The first run will also automatically install dependencies via CocoaPods (this may take a while). After a while, you should see the app on the virtual iPhone. If something goes wrong, make sure that Xcode has been installed and updated and that the simulator is configured correctly. (Alternatively, you can run the iOS application manually by opening the .xcworkspace project in Xcode and clicking “Run”, which sometimes gives a better insight into errors).
6. Edit the code and use Fast Refresh: Open the App.js file in your CLI project and change the header text, for example. Then save the file – on the emulator/phone you will see that the application will automatically reload, presenting the changes you made (thanks to the Fast Refresh mechanism, which works here similarly to Expo). In case of more significant native changes (e.g. adding a new native library), it may be necessary to rebuild the application.
Now you have a React Native project running that was created using the CLI. From this point on, you can build your app, add libraries via npm/yarn and fully develop your project. Please note that you can find more detailed information (e.g. about generating APK/IPA release files, configuring app signatures, etc.) in the React Native documentation.
Which solution should I choose?
The choice between Expo and React Native CLI depends on your level of experience and the specifics of the project you want to work on. Below you will find recommendations tailored to different user groups:
For beginners
If you are just starting out with React Native or mobile development in general, Expo might be a better choice to start with. It allows you to avoid the hassle of setting up a native environment and focus on writing code in JavaScript/React right away. Expo offers a smoother introduction – quick prototyping and previewing how the application works without the frustration of Gradle or Xcode configuration. In practice, many tutorials for beginners recommend Expo as a first step. Expo will also work if you want to quickly prepare a simple project or prototype – e.g. for the purpose of demonstrating an idea or a project for your studies. The managed workflow means you don’t have to worry about the details – for example, adding camera support or localization comes down to installing an Expo package (expo-camera, expo-location) and using it right away, without fiddling with native configuration files. In addition, the Expo community and excellent documentation will help you at the beginning of your journey – if you encounter a problem, you are probably not the first person to have it, and the Expo forums are full of tips.
For intermediate users
If you have already taken your first steps and are starting to feel more confident with React Native, the answer to the question “Expo or CLI?” is: it depends on the needs of the project. You can continue to use Expo, especially if the project does not require unusual native functionalities. Expo has evolved a lot in recent years and even some quite complex applications can be developed in it without limitations. However, it is worth assessing whether you are approaching the limits of Expo’s capabilities. If you know that you will need, for example, integration with a native SDK from a manufacturer (which is not in Expo) in your project, or you want to optimize size and performance as much as possible, it may be a signal to consider switching to React Native CLI. A good strategy is to start development in Expo (for speed) and possibly “eject” to bare workflow when Expo starts to limit you.
Remember that leaving Expo will require you to configure the environment like for CLI, but Expo provides the expo prebuildcommand that will generate native projects for you. For intermediate developers, it is also important to broaden their skills. It might be worth trying to create a smaller side project in React Native CLI from scratch to understand the differences and native mechanisms.
To sum up: if your project fits the Expo capabilities and you value speed of development, stick with Expo. If you start to feel limited or want to deepen your knowledge of native development, React Native CLI will be the next step. Check out what a native application is.
For advanced users
For experienced React Native developers, especially those who also have knowledge of Android/iOS, React Native CLI is often the choice. At this level, you probably want full control over the project, continuous integration (CI/CD), unit and end-to-end testing on real devices, performance profiling, etc. React Native CLI gives you full control over this – there is no “black box” that does something for you, you control every aspect yourself. In a professional environment, CLI is also preferred because it is easier to maintain and develop a large project in the long term without worrying about externally imposed limitations. Furthermore, many advanced developers choose CLI because they often have to combine work on the React Native part with work on the native part of the application (e.g. adding native screens or modules written in Swift/Kotlin). If you are advanced, Expo can still be used for rapid prototyping or creating smaller applications/demos, but for serious, large implementations, you will probably choose React Native CLI for its flexibility.
It is worth noting that Expo is not opposed to advanced applications – you can, for example, use part of the Expo ecosystem (libraries with Expo SDK) in a project created by CLI, because it is still React Native underneath. However, the general rule is: Expo for convenience, CLI for full control. As one article put it, Expo is ideal for beginners or rapid prototyping, while React Native CLI appeals to developers who need deep access to native modules and maximum control over the project.
Summary
Expo vs. React Native CLI – both approaches have their strengths and weaknesses, and understanding their differences is key before starting a React Native project. Expo provides a quick start, simplicity and a rich set of tools from the start, making it a great choice for beginners in the world of mobile applications and for projects that can be completed within the available Expo modules. React Native CLI, on the other hand, gives you complete freedom, native code control and scalability, which is essential for large, demanding commercial projects.
When choosing a solution for yourself, consider both your level of experience and the requirements of the project. If you want it to be quick and easy, start with Expo. If you know from the start that you need custom native solutions or want to learn the native approach, React Native CLI might be better. Remember that there is always the possibility of migration: you can convert an Expo project into a bare React Native (CLI) project if necessary, and vice versa, you can use multiple Expo libraries in a CLI project (thanks to the so-called bare workflow in Expo).


