DEV Community

Alex Spinov
Alex Spinov

Posted on

Expo Router Has a Free File-Based Routing for React Native — Next.js for Mobile

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
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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' } });
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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 });
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)