React Native routing used to require manual stack configuration. Expo Router brings file-based routing to mobile — the same pattern you know from Next.js.
What is Expo Router?
Expo Router is a file-based router for React Native and web. Drop a file in app/, and it becomes a route. Works on iOS, Android, and web from the same codebase.
Why Expo Router
1. File-Based Routing
app/
├── _layout.tsx → Root layout
├── index.tsx → / (home screen)
├── about.tsx → /about
├── settings/
│ ├── _layout.tsx → Settings layout (tabs)
│ ├── index.tsx → /settings
│ └── profile.tsx → /settings/profile
├── blog/
│ └── [slug].tsx → /blog/:slug
└── (auth)/
├── login.tsx → /login
└── register.tsx → /register
2. Universal (iOS + Android + Web)
// app/index.tsx — renders on ALL platforms
import { View, Text, Pressable } from 'react-native';
import { Link } from 'expo-router';
export default function Home() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 24 }}>Welcome</Text>
<Link href="/about" asChild>
<Pressable><Text>About</Text></Pressable>
</Link>
</View>
);
}
Same code → iOS app, Android app, and website.
3. Type-Safe Navigation
import { useLocalSearchParams, router } from 'expo-router';
// app/blog/[slug].tsx
export default function BlogPost() {
const { slug } = useLocalSearchParams<{ slug: string }>();
return <Text>Post: {slug}</Text>;
}
// Navigate with type safety
router.push({ pathname: '/blog/[slug]', params: { slug: 'hello-world' } });
4. Layouts and Navigation Patterns
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
export default function TabLayout() {
return (
<Tabs>
<Tabs.Screen name="index" options={{ title: 'Home', tabBarIcon: HomeIcon }} />
<Tabs.Screen name="search" options={{ title: 'Search', tabBarIcon: SearchIcon }} />
<Tabs.Screen name="profile" options={{ title: 'Profile', tabBarIcon: ProfileIcon }} />
</Tabs>
);
}
5. API Routes (Full-Stack Mobile)
// app/api/users+api.ts
export function GET(request: Request) {
const users = await db.users.findMany();
return Response.json(users);
}
export function POST(request: Request) {
const body = await request.json();
const user = await db.users.create(body);
return Response.json(user, { status: 201 });
}
6. Deep Linking (Automatic)
// Expo Router auto-generates deep link config
// myapp://blog/hello-world → app/blog/[slug].tsx
// https://myapp.com/blog/hello-world → same component
// No manual linking configuration needed
Expo Router vs React Navigation
| Expo Router | React Navigation | |
|---|---|---|
| Routing | File-based | Manual config |
| Web support | Built-in | Limited |
| Deep linking | Automatic | Manual config |
| Type safety | Built-in | TypeScript setup |
| API routes | Yes | No |
| SEO (web) | Head component | No |
| Learning curve | Low (Next.js-like) | Moderate |
Getting Started
npx create-expo-app@latest --template tabs
cd my-app
npx expo start
The Bottom Line
Expo Router is the missing piece for React Native. File-based routing, universal (iOS/Android/Web), type-safe navigation, and API routes. Build a mobile app as easily as a Next.js website.
Need data tools? I build scraping solutions. Check my Apify actors or email spinov001@gmail.com.
Top comments (0)