> expo-router
Build native mobile apps with file-based routing using Expo Router — React Native navigation that works like Next.js. Use when someone asks to "add navigation to React Native", "Expo Router", "file-based routing for mobile", "deep linking in React Native", "mobile app navigation", or "React Native routing like Next.js". Covers file-based routes, layouts, deep linking, tabs, stacks, and universal links.
curl "https://skillshub.wtf/TerminalSkills/skills/expo-router?format=md"Expo Router
Overview
Expo Router brings file-based routing to React Native — the same pattern as Next.js but for mobile apps. Drop a file in app/, get a screen. Folder structure defines navigation hierarchy: stacks, tabs, drawers, and modals. Deep linking works automatically — every route has a URL. Build iOS, Android, and web from one codebase with the same routing system.
When to Use
- Building a React Native / Expo app that needs navigation
- Want file-based routing instead of manual React Navigation config
- Need deep linking and universal links without extra setup
- Building a universal app (iOS + Android + Web)
- Migrating from React Navigation to a simpler routing model
Instructions
Setup
npx create-expo-app@latest my-app --template tabs
cd my-app
npx expo start
File-Based Routes
app/
├── _layout.tsx # Root layout (wraps all screens)
├── index.tsx # / (home screen)
├── about.tsx # /about
├── (tabs)/ # Tab navigation group
│ ├── _layout.tsx # Tab bar configuration
│ ├── index.tsx # First tab (home)
│ ├── explore.tsx # Second tab
│ └── profile.tsx # Third tab
├── settings/
│ ├── _layout.tsx # Stack layout for settings
│ ├── index.tsx # /settings
│ ├── account.tsx # /settings/account
│ └── notifications.tsx # /settings/notifications
├── [id].tsx # /123 (dynamic route)
├── post/
│ └── [slug].tsx # /post/my-first-post
└── +not-found.tsx # 404 screen
Root Layout
// app/_layout.tsx — Root layout with stack navigation
import { Stack } from "expo-router";
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="settings" options={{ title: "Settings" }} />
<Stack.Screen
name="modal"
options={{ presentation: "modal", title: "Info" }}
/>
</Stack>
);
}
Tab Navigation
// app/(tabs)/_layout.tsx — Bottom tab bar
import { Tabs } from "expo-router";
import { Ionicons } from "@expo/vector-icons";
export default function TabLayout() {
return (
<Tabs screenOptions={{ tabBarActiveTintColor: "#007AFF" }}>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: ({ color }) => <Ionicons name="home" size={24} color={color} />,
}}
/>
<Tabs.Screen
name="explore"
options={{
title: "Explore",
tabBarIcon: ({ color }) => <Ionicons name="compass" size={24} color={color} />,
}}
/>
<Tabs.Screen
name="profile"
options={{
title: "Profile",
tabBarIcon: ({ color }) => <Ionicons name="person" size={24} color={color} />,
}}
/>
</Tabs>
);
}
Navigation and Dynamic Routes
// app/(tabs)/index.tsx — Home screen with navigation
import { Link, router } from "expo-router";
import { View, Text, Pressable, FlatList } from "react-native";
export default function HomeScreen() {
const posts = usePosts();
return (
<View>
{/* Declarative navigation */}
<Link href="/about">About</Link>
<Link href="/settings">Settings</Link>
<Link href="/post/hello-world">My Post</Link>
{/* Programmatic navigation */}
<Pressable onPress={() => router.push("/settings/account")}>
<Text>Go to Account</Text>
</Pressable>
{/* Dynamic routes */}
<FlatList
data={posts}
renderItem={({ item }) => (
<Link href={`/post/${item.slug}`}>
<Text>{item.title}</Text>
</Link>
)}
/>
</View>
);
}
// app/post/[slug].tsx — Dynamic route screen
import { useLocalSearchParams } from "expo-router";
export default function PostScreen() {
const { slug } = useLocalSearchParams<{ slug: string }>();
const post = usePost(slug);
return (
<View>
<Text style={{ fontSize: 24 }}>{post?.title}</Text>
<Text>{post?.content}</Text>
</View>
);
}
Deep Linking (Automatic)
// app.json — Deep linking just works
{
"expo": {
"scheme": "myapp",
"web": { "bundler": "metro" }
}
}
Every route automatically gets a URL:
myapp://→ Home screenmyapp://post/hello-world→ Post screenhttps://myapp.com/post/hello-world→ Same screen (universal links)
Examples
Example 1: Build a social media app navigation
User prompt: "Set up navigation for a social app — tabs for feed/search/profile, stack for post details, and modal for creating posts."
The agent will create tab layout, nested stack routes, and a modal route with proper animations and deep linking.
Example 2: Add authentication flow
User prompt: "Add login/signup screens that show before the main app tabs."
The agent will create a route group for auth screens, use layout redirection based on auth state, and protect tab routes.
Guidelines
- File = route —
app/about.tsx=/aboutscreen _layout.tsxfor navigation containers — Stack, Tabs, Drawer(group)for route groups — organize without affecting URL[param]for dynamic routes — access viauseLocalSearchParams- Deep linking is automatic — every route has a URL
Linkfor declarative,routerfor programmatic — navigation+not-found.tsxfor 404 — catches unmatched routes- Typed routes —
hrefautocompletes with TypeScript - Web support — same routes work on web with
expo-router presentation: "modal"in options — for modal screens
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zoho
Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> zipkin
Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.