22

I did a lot of research now to find out the exact differences and trade-offs between a React Native project, CRNA and an Expo project.

My main guidance was this

However I still don't understand what (dis-)advantages I have using ExpoKit with native code vs. a normal React Native project with native code, apart from the fact that I can't use Expo APIs in a normal React Native project.

I know that when I start a project in Expo I can eject it either as ExpoKit project or as React Native project. In both I can use native code. In ExpoKit I can still use the Expo APIs in a normal React Native project I can't.

So my questions:

  1. What would be my interest to use a react native project if I can use native code and all Expo APIs in an ExpoKit project? In an ExpoKit project I can still use all Expo APIs and all React Native APIs, right?!

  2. Could I use Expo APIs in a React Native project if I install expo with npm install --save expo?

  3. What is the difference between React Native API and Expo API?

Benjamin Heinke
  • 2,802
  • 1
  • 17
  • 30
  • Question 1: In a React Native project I could uninstall all unnecessary libraries that come with an Expo project by default to make my app leaner. – Benjamin Heinke Mar 16 '18 at 20:26
  • Question 3: I suppose is has to do with the fact that the Expo SDK does always lags behind with the compatibility of the React Native Version. Currently Expo SDK (version 25.0.0) supports React Native 0.52.0 even though the current version of React Native is 0.54. So features added starting from version 0.52.0 cannot be used in Expo SDK. – Benjamin Heinke Mar 16 '18 at 20:28
  • 1
    Normally Expo SDKs release within 2-3 weeks after a corresponding React Native release. The version lag you're referring to is unusual: https://blog.expo.io/sdk-26-delayed-until-end-of-march-d02243e6ae7e – dikaiosune Mar 16 '18 at 21:21
  • Note: ExpoKit has been deprecated. From Expo's documentation: "ExpoKit is deprecated and support for ExpoKit will be removed after SDK 38. We recommend ejecting to the bare workflow instead." – Rap Aug 06 '20 at 14:21

2 Answers2

23

ExpoKit is kind of a hybrid between "pure JS" Expo apps and "vanilla" React Native. At its core it's still a React Native project, but a few things differ about the build system, developer experience, and features available.

Features

As of today, most of the APIs in Expo's SDK are not available in a vanilla React Native project, but they are available in ExpoKit. We think this might change in the future, but it'll be a lot of work.

Expo's push notification service does not currently work in ExpoKit, nor for vanilla React Native.

Build System

Both vanilla RN apps and ExpoKit apps use Xcode and Android Studio to build the native code. iOS ExpoKit apps use CocoaPods to install dependencies, which can add a little bit of complexity to managing the native build. Android ExpoKit apps have additional Gradle configuration to build multiple versions of React Native into the same binary (this is used to enable over-the-air updates of multiple SDK versions of JS), which can sometimes increase the complexity of adding other React Native libraries.

The JavaScript for an ExpoKit and React Native project is built by Metro, although in ExpoKit you need to run Metro using Expo's XDE or exp tools so that they can handle extra configuration for the project. This means you run a command like exp start rather than react-native run-android.

Due to the current design of ExpoKit (although this may change in the future), some open source React Native libraries may have compatibility issues with ExpoKit. For example, if a native library expects to be able to request a reference to React Native's OkHttp instance on Android, there may be a type mismatch when running inside ExpoKit due to the namespacing Expo uses to allow multiple versions of React Native to compile. That said, these issues tend to be pretty rare, and we're working on a few different ways for ExpoKit to be more and more compatible with libraries in the ecosystem.

This multi-version support also means that ExpoKit binaries tend to be larger than corresponding vanilla React Native binaries, although that may change in the future.

Your subquestions

  1. Some developers prefer to manage how their JS bundles and assets are distributed themselves, or they may need a library which isn't currently compatible with ExpoKit. Binary size is another reason why you may prefer vanilla RN.
  2. It's not currently possible to use most Expo APIs in a React Native project. Some APIs available in the Expo SDK are bundled from open source projects (such as react-native-maps) and can be used with a vanilla RN project.
  3. I'm not sure how to parse this question -- Expo APIs are currently just React Native APIs which know how to talk to each other and make certain assumptions about the environment they're running in.

Question from comment 1: You can modify the ExpoKit build all you want, although it may make it slightly harder to upgrade to a newer SDK release depending on how heavily you edit it.

dikaiosune
  • 1,055
  • 9
  • 7
  • Thank you for that detailed explanation. To response of question 3: To what I understand there is a difference between RN APIs and Expo APIs, since there are APIs that can only be used with Expo not even ExpoKit (push-notification). And others work with ExpoKit but not with a vanilla RN project (asset manager). The majority is probably the same APIs, but is there any detailed list that lists the APIs from Expo and their corresponding compatibility? Or a bit more information about the difference between the RN APIs and Expo APIs. – Benjamin Heinke Mar 19 '18 at 14:36
  • These distinctions are actually a bit fuzzy in terms of technical details. We don't currently have a comparison chart, although the docs for each API should describe where it's supported. – dikaiosune Mar 20 '18 at 17:22
0

Note to anyone who stumbles across this after 2020 ... ExpoKit has been deprecated so this whole question is moot.

From Expo's documentation: "ExpoKit is deprecated and support for ExpoKit will be removed after SDK 38. We recommend ejecting to the bare workflow instead."

Rap
  • 6,851
  • 3
  • 50
  • 88