Overview
Expo Router is a routing library specifically engineered for React Native applications within the Expo ecosystem, extending its capabilities to also support web applications from a single codebase. It adopts a file-system based approach, where the structure of files and folders within a designated app directory directly defines the application's navigation paths and screens. This contrasts with traditional imperative routing solutions, offering a declarative way to manage complex navigation hierarchies and deep links across mobile and web platforms.
The primary goal of Expo Router is to streamline the development of universal applications by providing a unified routing solution that works seamlessly on iOS, Android, and the web. This enables developers to share significant portions of their codebase, including navigation logic, between native mobile and web interfaces. It supports common navigation patterns such as stack navigation, tab navigation, and drawer navigation, abstracting the underlying native navigation primitives provided by platforms like iOS and Android. For example, it utilizes React Navigation's core components under the hood for native experiences, while adapting to web standards for browser-based routing.
Expo Router is particularly well-suited for developers building new React Native projects with Expo, or those migrating existing projects to a universal architecture. Its file-based convention reduces boilerplate code for route declaration and simplifies the process of adding new screens and nested navigators. It also offers features like static site generation (SSG) for web builds, allowing for SEO-friendly and performant web applications derived from the same React Native codebase. This makes it a viable alternative for projects that might otherwise consider separate web frameworks like Next.js for web routing while still aiming for a single codebase for native.
Deep linking is a core feature, allowing applications to respond to specific URLs, whether from web links, push notifications, or other apps. Expo Router handles the parsing and navigation to the correct screen based on the incoming URL schema. This functionality is crucial for modern mobile applications that need to offer rich user experiences and seamless integration with external services. The library is open-source and maintained by the Expo team, benefiting from continuous development and integration with the broader Expo SDK.
Key features
- File-System Based Routing: Defines navigation paths automatically based on the directory structure of application files, simplifying route management (Expo Router introduction).
- Universal Navigation: Provides a single API for navigation across iOS, Android, and web platforms, facilitating code sharing and reducing platform-specific logic.
- Deep Linking: Built-in support for handling deep links, allowing applications to navigate to specific screens from external URLs or notifications (Expo Router deep linking guide).
- Static Site Generation (SSG): Enables the generation of static HTML files for web applications, improving initial load times and SEO for web builds from a React Native codebase.
- Nested Layouts: Supports complex navigation hierarchies with nested layouts, allowing for sophisticated UI structures and shared layouts across multiple screens.
- Authentication Flows: Includes utilities and patterns for implementing protected routes and authentication-driven navigation flows.
- Dynamic Routes: Allows for routes with dynamic segments (e.g.,
[id].js) to handle variable parameters in URLs, similar to web frameworks. - Error Handling: Provides mechanisms for custom error pages and handling not-found routes for a robust user experience.
Pricing
Expo Router is an open-source library and is free to use.
| Product/Service | Pricing Model | Details | As of Date |
|---|---|---|---|
| Expo Router | Free and Open-Source | Available for use under an open-source license with no direct costs. | 2026-06-09 |
Common integrations
- React Native: Expo Router is designed specifically for React Native applications, allowing comprehensive routing within the framework (React Native documentation).
- Expo SDK: Integrates seamlessly with the entire Expo ecosystem, leveraging other Expo modules for features like asset management, push notifications, and development tools (Expo Go overview).
- React Navigation: Utilizes core components and patterns from React Navigation for native navigation primitives, providing a robust foundation (React Navigation homepage).
- TypeScript: Fully supports TypeScript for type-safe routing and improved developer experience (TypeScript documentation).
Alternatives
- React Navigation: A popular, community-driven navigation solution for React Native, offering imperative and declarative APIs for stack, tab, and drawer navigators.
- Next.js: A React framework for building web applications, featuring a file-system based router, server-side rendering, and static site generation.
- Remix: A full-stack web framework that uses web standards for routing, nested layouts, and data handling, focused on performance and developer experience.
Getting started
To begin using Expo Router in a new Expo project, you first need to create a new Expo project and then set up the router. This example demonstrates a basic setup with a single index page and a dynamic user profile page.
# Create a new Expo project
npx create-expo-app my-app
# Navigate into your project directory
cd my-app
# Install Expo Router (it's often included with newer Expo templates)
npx expo install expo-router react-native-safe-area-context react-native-screens
# Modify your package.json to include the "main" entry for Expo Router
# Add the following entry:
# "main": "expo-router/entry"
# Example package.json snippet:
# {
# "name": "my-app",
# "version": "1.0.0",
# "main": "expo-router/entry",
# "scripts": {
# "start": "expo start",
# "android": "expo start --android",
# "ios": "expo start --ios",
# "web": "expo start --web"
# },
# "dependencies": {
# "expo": "~50.0.14",
# "expo-status-bar": "~1.11.1",
# "react": "18.2.0",
# "react-native": "0.73.6",
# "expo-router": "~3.4.8",
# "react-native-safe-area-context": "4.8.2",
# "react-native-screens": "~3.29.0"
# },
# "devDependencies": {
# "@babel/core": "^7.20.0"
# },
# "private": true
# }
# Create an 'app' directory for your routes
mkdir app
# Create an index page (app/index.js)
app/index.js
import { Link } from 'expo-router';
import { Text, View } from 'react-native';
export default function Page() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home Screen</Text>
<Link href="/user/123" style={{ color: 'blue', marginTop: 20 }}>
Go to User Profile 123
</Link>
<Link href="/user/456" style={{ color: 'blue', marginTop: 10 }}>
Go to User Profile 456
</Link>
</View>
);
}
app/user/[id].js (for dynamic routes)
import { useLocalSearchParams } from 'expo-router';
import { Text, View, StyleSheet } from 'react-native';
export default function UserProfile() {
const { id } = useLocalSearchParams();
return (
<View style={styles.container}>
<Text style={styles.text}>User Profile ID: {id}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 24,
fontWeight: 'bold',
},
});
# Start your Expo development server
npx expo start
This setup creates two routes: / (mapped to app/index.js) and /user/:id (mapped to app/user/[id].js). The Link component from expo-router handles navigation between these screens, and useLocalSearchParams allows access to dynamic route parameters like id.