Skip to main content



Expo Router brings the best routing concepts from the web to native iOS and Android apps. Every file in the app directory automatically becomes a route in your mobile navigation, making it easier than ever to build, maintain, and scale your project. It's built on top of our powerful React Navigation suite enabling truly native navigation. The entire deep linking system is automatically generated live, so users can share links to any route in your app.

Quick Start

Run the following to create a project with expo-router setup:

npx create-expo-app@latest --example with-router

Example source.


  • Native Truly native navigation with the most cutting-edge developer experience.
  • Deep linking Every screen in your app is automatically deep linkable. Making any part of your app shareable.
  • Offline-first Apps are cached and run offline-first, with automatic updates when you publish a new version. Handles all incoming native URLs without a network connection or server.
  • Scale Apps are built with a modular architecture that scales to any size. Refactoring and upgrading are a breeze due to the declarative nature of the API.
  • Iteration Universal Fast Refresh across iOS, Android, and web along with artifact memoization in the bundler keep you moving fast at scale.
  • Cross-Platform Expo Router is a large step toward universal React apps. The same codebase can be used to build iOS, Android, and web apps.

Getting Started


This guide has moved to the Expo Docs.

Expo Router supports expo@48.0.0 and greater.

Ensure your computer is setup for running an Expo app.

Create a new Expo project:

npx create-expo-app

Install expo-router and peer dependencies:

npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar react-native-gesture-handler

Then delete the entry point in your package.json, or replace it with index.js to be explicit:

"main": "index.js"

Create a new file index.js in the root of your project. If it exists already, replace it with the following:

import "expo-router/entry";

Add a deep linking scheme and enable metro web in your app.json (or app.config.js):

"expo": {
"scheme": "myapp",

"web": {
"bundler": "metro"

Additional setup for v1

If you're using Expo Router v1, you need to resolve to metro@0.76.0. Expo Router v2+ should delete resolutions and overrides on metro packages.

If you use Yarn:

"resolutions": {
"metro": "0.76.0",
"metro-resolver": "0.76.0"

If you use npm, this requires npm 8.3.0 or higher. You can install this with npm i -g npm@^8.3.0. After that, configure overrides in package.json:

"overrides": {
"metro": "0.76.0",
"metro-resolver": "0.76.0"

Configure the Babel plugin

module.exports = function (api) {
return {
presets: ["babel-preset-expo"],
plugins: ["expo-router/babel"],


Start the server with:

npx expo --clear

Then open by pressing i, a, or w for web (only tested against Metro web).

Create files in the app directory and they will be automatically added to the app.


If you run into any issues, please check the troubleshooting guide. If you're still running into problems, please open an issue.

Next Steps