Expo: A Monorepo for Universal React Native Apps, From SDK to EAS
Framework for building universal native apps with React and JavaScript that run on Android, iOS, and the web, including an SDK, Modules API, CLI, and router.
At a glance
- What is it?
- Expo is an open-source framework for building native Android, iOS, and web apps with React. This review examines its architecture, workflows, and trade-offs for engineers deciding whether to adopt it.
- Who is it for?
- Adopt Expo if you are building a universal React app and want a managed workflow with first-class web support and hosted build services. Avoid it if you need deep control over native code or if your team cannot commit to the Expo toolchain's conventions.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Expo Actually Solves
Expo solves the problem of building native mobile apps without maintaining separate iOS and Android codebases. It provides a universal runtime and libraries that let you write apps in React and JavaScript, and those apps run on Android, iOS, and the web. The target audience is broad: individual developers and teams who want to ship to multiple platforms from a single codebase. The repository description makes this explicit: "an open-source platform for making universal native apps." This is not a niche tool; it is a full framework that includes the SDK, a CLI, a router, and even a Go app for testing. For engineers, the core value is avoiding the overhead of native development while retaining the ability to write truly native apps, not just web wrappers.
Inside the Monorepo: SDK, CLI, and Supporting Tools
The repository is a monorepo with a clear layout. The `packages` directory contains all source code for Expo modules, which is where you edit a library or inspect its internals. The `apps` directory holds Expo projects linked to development modules, and `apps/expo-go` contains the source for the Expo Go client. There is also a `react-native-lab` directory, which is a fork of `react-native` used specifically to build Expo Go. This is a critical detail: Expo does not just wrap React Native; it maintains its own fork for its client. The presence of `docs`, `templates`, and `tools` directories shows that this is a full ecosystem, not just a library. The `template-files` directory contains templates for files that require private keys, populated via `template-files/keys.json`. This structure is typical for a mature open-source project, but it also means that contributing to Expo requires understanding a complex build system with multiple moving parts.
How Expo Works: The Universal Runtime and Modules API
The documentation states that Expo includes a universal runtime and libraries that allow you to build native apps by writing React and JavaScript. The mechanism is straightforward: your React code runs on a JavaScript engine, and Expo provides native modules that bridge to platform-specific APIs. The "Modules API" is a key component, as it offers a structured way to create and use native modules within Expo. The repository layout shows that these modules live in `packages`, and they are designed to work across Android, iOS, and web. The Expo Go app is a client that can run your app instantly, which is useful for testing. The CLI, located in `packages/@expo/cli`, is the tool you use to create and manage projects. This is not a black box; you can inspect the source of every module. However, the actual data flow between JavaScript and native code is not fully documented in the README, so you would need to consult the API reference for specifics.
Getting Started: Commands and Configuration
To start a new project, the README points to the template projects in `templates`, and the command is `npx create-expo-app`. This is the standard entry point. Once you have a project, you can run it in the Expo Go app, which is available on Android and iOS. The README also mentions "Try Expo in the Browser" via Snack, which is a web-based editor. For configuration, the documentation is hosted at docs.expo.dev, and the repository includes a `docs` directory with the source for those docs. The `template-files/ios/dependencies.json` specifies the CocoaPods dependencies for iOS, which is relevant if you are working on the native side. For basic usage, you do not need to touch configuration files manually; the CLI handles most setup. However, if you need custom native modules, the documentation has a section on "Using Custom Native Modules," which suggests that you can go beyond the managed workflow.
EAS: The Hosted Services Layer
Expo Application Services (EAS) is a platform of hosted services that are "deeply integrated" with the open source tools. The README describes EAS as helping you "build, ship, and iterate on your app." This is a significant part of the Expo ecosystem, but it is not open source; it is a hosted service. This means that while the core framework is free and MIT-licensed, you may end up paying for EAS to handle builds and deployments. The integration is deep, meaning that the CLI likely has commands to interact with EAS, but the README does not specify those commands. For engineers, this is a trade-off: you get convenience, but you become dependent on a third-party service for critical parts of your workflow. If you prefer to self-host your build infrastructure, you need to be aware that EAS is a separate product with its own pricing and terms.
Limitations and When Expo Is the Wrong Tool
One limitation is that Expo Go, the client app, uses a fork of React Native (`react-native-lab`). This means that if you need a specific React Native version or a native module that is not included in Expo Go, you may have to eject or use a development build. The README does not mention ejection explicitly, but the existence of a fork implies that you are constrained to the versions that Expo supports. Another limitation is the reliance on EAS for hosted services; if you have strict data sovereignty or security requirements, you may not want to use a cloud service. Also, the monorepo is large and complex, which is fine for contributors but not relevant to end users. For apps that require heavy custom native code, such as low-level Bluetooth or custom rendering engines, Expo's managed workflow might be restrictive. The documentation's "Using Custom Native Modules" section suggests there is a path, but it adds complexity.
Alternatives: React Native CLI and Bare Workflow
The main alternative is the React Native CLI, which gives you direct control over the native projects. With the React Native CLI, you manage the iOS and Android projects yourself, and you can add any native module without constraints. The difference in approach is fundamental: Expo abstracts away the native projects, while the React Native CLI exposes them. If you use the React Native CLI, you do not get Expo's universal runtime or its built-in web support; you would need to add libraries like `react-native-web` yourself. Another alternative is a bare workflow within Expo, where you can "eject" and take control, but the README does not describe this. The choice depends on your need for control versus convenience. Expo is the right tool if you want to move fast and avoid native build configuration, but the React Native CLI is better if you need to customize every aspect of the native build.
Maintenance, Licensing, and Upgrade Costs
The project is MIT-licensed, which is permissive and allows commercial use. Some dependencies are licensed differently, such as BSD, so you should check the licenses of any packages you use. The repository is actively maintained, with a default branch of `main` and a large community, but the README does not provide release cadence or versioning details. Upgrade costs are a real concern: because Expo maintains its own fork of React Native, upgrading to a new React Native version may lag behind the upstream release. You also need to consider that EAS is a hosted service, so your build pipeline is tied to Expo's infrastructure. The `template-files` directory with private keys suggests that some configuration is generated, which could be a maintenance burden if you fork the repo. Overall, the project is well-structured for contributors, but end users should expect to follow the release notes and test upgrades carefully.
Editorial conclusion
Adopt Expo if you are building a universal React app and want a managed workflow with first-class web support and hosted build services. Avoid it if you need deep control over native code or if your team cannot commit to the Expo toolchain's conventions. Before adopting, verify that the SDK version you need is compatible with your target React Native version and that your custom native modules are supported by the Expo Modules API. The repository's structure and the presence of EAS indicate a strong commitment to a hosted, integrated workflow, but the actual maturity of your specific use case depends on the current SDK release.
Community notes