Expo: a universal runtime for React Native apps on Android, iOS and the web
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 packages a runtime, a module API, a CLI and a file-based router so one React codebase can target three platforms. The repository is a pnpm monorepo, and the parts you actually install come from npm, not from a clone.
- Who is it for?
- Adopt Expo if you want one React codebase for Android, iOS and the web and you are willing to work inside its module API and its release cadence. Do not adopt it if your app depends on native code you cannot express as an Expo module, or if you need to pin a React Native version that the current SDK does not support.
- 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 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Expo solves for React Native teams
React Native gives you a JavaScript runtime and a set of native components, but it does not give you a project structure, a module system for native code, a router, or a way to run the same code on the web. Expo fills those gaps. The README describes it as "an open-source platform for making universal native apps that run on Android, iOS, and the web", and the repository backs that up with a universal runtime plus libraries that let you build native apps by writing React and JavaScript.
The audience is specific. You are building a product that has to exist on phones and in a browser, you want to write it once in React, and you do not want to maintain three build pipelines by hand. Expo is less useful if you are writing a single-platform app with heavy custom native code, because the abstraction adds a layer between you and the platform SDKs.
One thing the README makes explicit: the repository is not the product you install. It holds the Expo SDK, the Modules API, the Go app, the CLI, the Router, the documentation and supporting tools. Expo Application Services (EAS) is described separately as "a platform of hosted services that are deeply integrated with Expo open source tools", which matters when you are deciding what is free and what is a paid service.
What is actually inside the expo/expo monorepo
The repository layout is the clearest statement of how the project is organised. `packages` holds the source for Expo modules, which is where you look if you want to read how a library works or change it. `apps` holds Expo projects linked to development modules and is where testing happens. `apps/expo-go` holds the Expo Go client source, and the README notes that on iOS you open `apps/expo-go/ios/Exponent.xcworkspace` rather than `Exponent.xcodeproj`, because the workspace also loads the CocoaPods dependencies.
Other directories matter for contributors more than for users. `docs` is the source for docs.expo.dev. `templates` holds the projects you get when you run `npx create-expo-app`. `react-native-lab` is described as the project's fork of react-native used to build Expo Go, which is a useful signal: Expo Go tracks its own React Native build rather than the upstream release line. `tools` and `template-files` handle build and configuration, and `template-files/ios/dependencies.json` specifies the app's CocoaPods dependencies.
The root `package.json` is private and versioned 1.4.0, so it is not a published artifact. It declares pnpm 12.2.1 through `devEngines` and uses `turbo` 2.10.12 to drive `build`, `typecheck`, `lint`, `test` and `format` through `./bin/expo-turbo`. There is a deliberate guard: running `tsc` at the workspace root prints an instruction to run it from an individual package and exits with status 1.
Installing Expo and running a first app
The README points to docs.expo.dev for getting started and names `npx create-expo-app` as the scaffolding command. The templates it uses live in the repository's `templates` directory, and the README lists `npx create-expo-app` as the way you get them. The README gives this example of the command, and the surrounding prose in the README is what tells you it produces a project directory with its own dependencies.
npx create-expo-appThe README also links a browser-based option, Snack, at snack.expo.dev, labelled "Try Expo in the Browser". That is the fastest way to check whether the runtime behaves the way you expect before installing anything locally.
Once the project exists, the CLI starts the development server. The README links the CLI package at `packages/@expo/cli` for anyone working on the CLI itself, which is a different task from using it. The README's badges section shows the block below as the way to let others run your app instantly in Expo Go, and it is the only other snippet the README reproduces in full.
[](https://expo.dev/client)
[](https://expo.dev/client)What you should see, according to the README's own description, is a project that can be opened in Expo Go through that client link. Note the scope: the README does not document the flag set of the CLI's start command, and it does not describe rollback or downgrade behaviour. Those details live in the docs site, which is the source to check before you rely on a specific workflow.
Where Expo stops being the right choice
The README does not document rollback, and it does not document a support window for older SDK versions. That silence is the limitation worth taking seriously. Expo ships as a coordinated set of packages, and the repository's own layout reflects it: modules are versioned together, Expo Go is built from a forked React Native, and the root workspace pins a single package manager version. If your app sits in a large monorepo with its own React Native pin, moving to an Expo SDK can mean moving several dependencies at once.
The second boundary is native code. Expo provides a Modules API and a documented path for custom native modules, but every native dependency you add outside that path is something the universal runtime cannot reason about. An app whose core value is a vendor SDK with its own binary distribution is a poor fit until that SDK has an Expo module.
Finally, EAS is a hosted service. The README frames it as a platform "deeply integrated with Expo open source tools", which is accurate but also a reminder that the build and release workflow the docs describe may depend on an account and a service, not only on the MIT-licensed code in this repository.
Expo Router and the alternative of bare React Native
The repository ships a Router alongside the SDK, and the README lists it as one of the components of the repository. That matters because routing is where the universal claim becomes concrete: a file-based router can map the same route tree to a native navigation stack and to browser URLs, which is harder to do if you assemble navigation yourself per platform.
The obvious alternative is bare React Native without Expo. The difference is not performance, it is who owns the integration surface. Bare React Native leaves you to wire up navigation, asset handling, fonts, permissions and the web target, and in exchange you control every native dependency directly and can pin React Native to whatever version you want. Expo takes that integration surface and maintains it as a versioned SDK, which shortens setup and makes the three platforms behave alike, at the cost of adopting the SDK's release cadence and its module conventions. If your team already has a working bare setup with custom native code, migrating to Expo is a real project, not a config change. If you are starting fresh and the platform APIs you need are covered, the Expo path removes a large amount of assembly work.
Licence and the cost of keeping up
The README states that "The Expo source code is made available under the MIT license" and adds that some dependencies are licensed differently, with the BSD license given as an example. The repository also carries a THIRD-PARTY-LICENSES file at the root, which is where to look before shipping a build, because MIT on the framework does not automatically mean MIT on everything linked into your binary. This is a description of what the repository says, not legal advice; a review of the third-party file is the concrete step.
On upgrade cost, the repository supports the claim that upgrades are coordinated rather than incremental. The root workspace pins pnpm 12.2.1 and turbo 2.10.12, uses a single lockfile, and routes all build and test tasks through `./bin/expo-turbo`. There is a `CHANGELOG.md` and a `changelogVersions.json` at the root, so the changelog is the mechanism the project provides for tracking what changed between versions. What the README does not provide is a stated support policy for old SDKs, so the practical question for a team is how many SDK releases per year they can absorb, not whether an upgrade path exists.
Editorial conclusion
Adopt Expo if you want one React codebase for Android, iOS and the web and you are willing to work inside its module API and its release cadence. Do not adopt it if your app depends on native code you cannot express as an Expo module, or if you need to pin a React Native version that the current SDK does not support. Before committing, verify three things: which SDK version the template project pulls today, whether the native APIs your app needs already exist as Expo modules, and how your team will handle upgrades, because the SDK moves as a unit and the repository carries no published upgrade policy beyond the changelog and docs.
Frequently asked questions
What is Expo and what is Expo Go?
Expo is an open source platform for making universal native apps that run on Android, iOS and the web, built on React and JavaScript. Expo Go is the client app whose source lives in apps/expo-go in the repository, and the README shows a badge that lets people run your app instantly in it.
What is Expo and what is Expo Router?
Expo is the framework and universal runtime; Expo Router is one of the components shipped in the same repository, listed in the README alongside the SDK, Modules API, Go app and CLI. The README does not describe Router's API, so its behaviour has to be checked in the docs.
Is Expo good?
The README positions it as a way to build native apps for Android, iOS and the web from one React codebase, and the repository is MIT licensed and not archived. Whether it fits depends on your native dependencies: anything outside the Expo Modules API is outside what the universal runtime handles.
What are some Expo examples?
The README points to Snack at snack.expo.dev as a way to try Expo in the browser, and to docs.expo.dev for getting started and the API reference. The repository's apps directory holds Expo projects linked to development modules, which is where the project does most of its own testing.
React Native Expo: what is Expo?
Expo is a universal runtime and set of libraries layered on React Native that let you build native apps by writing React and JavaScript, targeting Android, iOS and the web. The repository also carries its own fork of react-native in react-native-lab, which is the build used for Expo Go.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/expo-expo)
Community notes