Expo Modules Core is the only module that is bundled in. It is a small runtime library that defines the Expo Modules API used by other modules, and adds about 150 KB to a production build of an app downloaded from the stores. A hello world iOS app made with Expo ended up being smaller than the same hello world app that used RN without Expo due to the Xcode settings.
There are also no custom UI controls or animation libraries bundled with Expo. The Expo Go starter app includes a preset SDK, and when developers create a build for the app stores or a development build of their own app, only the libraries they use are included.
IMO it would be a meaningful improvement for the react-native package to provide the minimal runtime needed, namely JSI, Hermes, Turbo Modules, Yoga, Fabric, and perhaps a few primitive view components like View, ScrollView, and Text. The package provides more than a library needs. Animations and gestures today are better served in my experience by modules outside of the react-native package, like Reanimated and Gesture Handler that use truly native gestures. React Navigation uses the system navigator UI and Expo Router adds file-based routing and universal links. Expo Image adds support for modern image formats like AVIF and WebP and uses mature, performant image libraries like Glide and SDWebImage. So there is definitely still work to be done that can improve quality and reduce complexity in RN.
The hosted services offered by the Expo team called EAS has an implementation of an updates server that conforms to that protocol. If EAS went away or you wanted not to use EAS, you could write and operate your own server that conforms to the protocol instead.
Sometimes I tell people the best Expo apps have custom native code and it is a really useful skill to know Kotlin and Swift in addition to React and JavaScript. Glad to hear you have found Expo and EAS so useful! One of the features we'll be previewing during launch week is something Pinterest has been needing for a long time, and we'll make sure you hear about it.
A lot of the docs prioritize ease of getting started and EAS has a free plan generous enough to get you to production and often beyond. The Expo CLI docs have a section on building locally here: https://docs.expo.dev/more/expo-cli/#building
"npx expo prebuild" (covered in that link) is a good command to know. It generates "android" and "ios" directories with your Android Studio and Xcode projects, respectively. These projects can be built entirely locally and there is no dependency on EAS.
As a side note, the old "expo build" command also ran on hosted servers. It was part of the old Expo CLI, which, for historical reasons from six or seven years ago, didn't separate the free & open source Expo framework from the hosted offering. We built EAS years later, with a major new feature being support for builds that have custom native code. Keeping EAS decoupled from Expo has been a conscious effort, and we've also designed EAS to work with any React Native app whether it uses Expo or not.
It is technically possible, of course, though I vaguely recall iOS App Store guidelines saying not to just wrap an existing website in a webview. On the flip side, PWA support in Safari has been gradually improving with better support for web manifests and web notifications, for example.
Modern Expo is very different and in 2023, Expo has full support for custom native code and isn't a layer, so to speak. Ejecting is gone. React Native has also become much thinner in several ways. For instance, developers write Kotlin and Swift with the Expo Modules API and uses JSI (RN's "JavaScript Interface") to directly bind the native methods to Hermes JS methods.
Relatedly, the developer demographic has grown and a lot more developers are adding Kotlin and Swift to their skill sets. They write JS and React most of the time while also writing custom native code when they need to. Most of the best Expo apps include custom native code.
Test frameworks have also grown a lot. I suspect the issues with Detox were often from developers looking to use it with the Expo Go starter app that doesn't support custom native code. These days I hear a lot of positive things about Maestro as well and there was a nice talk on it at App.js Conf earlier this year: https://www.youtube.com/watch?v=uoCzBdFCoqc
EAS CLI is designed for EAS, the hosted services. It is intended to use your EAS account, which I suspect is why the PR wasn't accepted.
Expo CLI is for entirely local builds. Run "npx expo prebuild:{android,ios}" to generate your Android Studio and Xcode projects, and build them with the IDEs or their respective CLI tools directly.
Looking to always learn new things is great. If you find yourself looking to try out Expo and have completed the first setup steps, I'd suggest looking at making a development build of your app and the Expo Modules API for writing Kotlin and Swift code.
Almost all of the best apps made with Expo also have a small amount of custom native code. And I find it's just generally good to understand the abstraction layer above and the abstraction layer below the one you're working at to bring the two together the best you can.
This is actively being worked on. Also a big area of investment over the past couple of years has been adding support for custom native code to Expo and the Expo Modules spec. It is easier in several ways now to write your own module when an existing one doesn't work for you.
The Expo Go app needs to connect to a server for two reasons: the server gives you a signing certificate that is used to sign your project manifest, and it also fetches the list of active and recent projects and Snacks. It is certainly not intended to be invasive.
Expo Go is entirely optional and it is recommended to graduate early on in your development cycle to using a development build of your own app instead. Development builds don't sign project manifests (unless you're intentionally using end-to-end signed updates, an advanced feature). They are like regular development builds of a traditional native app.
Also if you'd like to keep using Expo Go, the signing certificate mentioned earlier has an expiry of 30 days or so IIRC, during which time you don't need to connect to a server. You may still want to provide the "--offline" flag to turn off refreshing the certificate.
These are a few things I can say as one of the Expo cofounders. We've worked on the Expo framework for over eight years, and did R&D for a year or two before that even before React Native was released. Many other companies and frameworks, even from very large companies, have come and gone in that time and Expo has endured. Paul Graham wrote he found determination "to be the most important quality in startup founders" for what you find that to be worth.
Also from the beginning we believed the Expo framework needs to be free and open source. Introspecting as developers ourselves, we thought people would be a lot more likely to try out and recommend open source frameworks and incrementally build up an ecosystem of modules and StackOverflow answers. Expo gives developers much more agency because it is open source. And it is really hard in my opinion to make a business from licensing developer tools, libraries, and frameworks. There are so many free alternatives.
The goal of the Expo framework is to be the ultimate way to build universal, native application software. Universal apps have builds for Android, iOS, the web, and future platforms. And the user experience is truly native to each respective platform, often by using the native system UI components and not a replica. It does take significant effort to maintain the Expo SDK's set of convenient APIs. It's also just one part of Expo overall.
Separately, the way we are building a business is by offering hosted services for React Native apps, called Expo Application Services (EAS for short). These are optional services for building and updating your apps and using the Expo framework doesn't require EAS. We find developers often use a combination of EAS for some tasks and their own hardware for others.
We work to build developer trust. We are a small company but try to serve developers and our customers well, sometimes better than the companies that have endless trunks of money (we've all seen killedbygoogle.com). So, that's some of how we think about things at Expo.
Part of Expo's approach is for Expo apps to be native apps that provide a user experience that is native to the underlying platform, whether it's Android, iOS, the web, or something new.
For instance, navigation is one of the more complicated parts of an app's UX. The navigator UI has many subtle behaviors and animations that have been built over the course of several years, like how the back button and screen headers transition in and out. The gestures often have invisible hit boxes that are hard to replicate without using the system UI components. The screen transitions use specific animation curves users expect. And there's non-visual behavior like supporting universal deep links that take the user to a specific screen, which tends to require quite a bit of work to implement.
Expo uses the system UI components and the behaviors described above are present. The goal is for Expo UI to be native UI. And in some aspects, Expo can already provide a better default user experience like with universal links. Every screen gets a URL with Expo Router since URLs are a first-class concept, like they are on the web. This lets us provide deep linking (navigate from URL to a screen) and universal linking (HTTPS links work across web and native) as default features.
Sometimes the way we talk about Expo is that it brings together the best of native and web, and a lot of that is the user experience of native applications with the developer experience of the web.
Expo is the free and open source framework and, separately, Expo Application Services (EAS) is the SaaS. Expo and EAS are designed to be decoupled while also working well together, optionally.
The Expo framework gives you the module system, runtime environment, CLI tools, debugger, a suite of modules, navigation to build universal native apps. They're universal in that there is an Android build, an iOS build, and a web build, and, especially with Expo Router, they work together with universal links. They're native in that the user experience is native to the underlying platform, usually using system UI components and behaviors.
EAS provides hosted services for building your app, submitting it to the stores, and updating it. Many developers will use both EAS and their own hardware. It is convenient and fast to build locally when iterating on a feature. And it is convenient in a different way to use EAS to make preview builds of your app on your PRs that change your app's native code or to make release candidates for production.
Expo these days is pretty extensible and the option to write your own IAP module is a bit easier with Expo Modules, which let you write custom modules with Kotlin and Swift and set up a config plugin to automate changes to your Android Studio and Xcode projects. It definitely would be good for more IAP modules to provide config plugins and automatically integrate with Expo.
The ability to write and run your own update server is a part of Expo Updates and it is not going to be removed. The Expo Updates protocol is an open specification here: https://docs.expo.dev/technical-specs/expo-updates-1/.
Separately, EAS provides an optional, hosted service that implements the server side of the standard Expo Updates protocol and supports both simple and more advanced deployment patterns, for instance: https://docs.expo.dev/eas-update/deployment-patterns/. It also integrates with EAS's build service and appeals to teams looking for managed cloud infrastructure.
Building Expo apps locally is not going to be removed. I am one of the cofounders of Expo.
Being able to build your app on your own hardware is a relatively fundamental feature of any application software framework. The Expo framework is free and open source and we consciously keep it decoupled from Expo Application Services (EAS), which is a suite of hosted services we manage.
Two of the ways to build your app are:
- Entirely locally, without EAS: generate your native Android and iOS projects with "npx expo prebuild:{android,ios}" and build your app with Android Studio/Gradle and Xcode/xcodebuild, respectively.
- With EAS: after getting set up with EAS, installing EAS CLI, and configuring eas.json, run "eas build". There is also a "--local" flag that runs the compilation steps locally and uses your signing credentials managed by EAS.
Many developers use a mix. For instance, they'll build locally when working on a feature for a fast feedback loop. And they'll use EAS to build their release candidates and PR previews to share with their team.
The Expo framework runs entirely on the end user's device. It's client-side software and I don't think MiTM attacks are the main part of the threat model. Like with most open source you may want to vet the supply chain and the code you include in your apps but Expo has been maintained for over seven years now and is generally trusted in this way in my experience.
There are also no custom UI controls or animation libraries bundled with Expo. The Expo Go starter app includes a preset SDK, and when developers create a build for the app stores or a development build of their own app, only the libraries they use are included.
IMO it would be a meaningful improvement for the react-native package to provide the minimal runtime needed, namely JSI, Hermes, Turbo Modules, Yoga, Fabric, and perhaps a few primitive view components like View, ScrollView, and Text. The package provides more than a library needs. Animations and gestures today are better served in my experience by modules outside of the react-native package, like Reanimated and Gesture Handler that use truly native gestures. React Navigation uses the system navigator UI and Expo Router adds file-based routing and universal links. Expo Image adds support for modern image formats like AVIF and WebP and uses mature, performant image libraries like Glide and SDWebImage. So there is definitely still work to be done that can improve quality and reduce complexity in RN.