Screens are the pages of a mobile app. Expo Router gives you file-based routing: a file in app/ becomes a route, and layout files define stacks and tabs. This is the structure your agent will fill in screen by screen.
Core concepts
- File-based routes:
app/index.tsxis the home route,app/settings.tsxis/settings, andapp/post/[id].tsxis a dynamic route. Folders group routes and_layout.tsxfiles wrap them. — Expo Router intro - Stacks, tabs and modals: A Stack pushes screens on top of each other, Tabs switch between top-level sections, and a modal presents a focused task. Combine them in nested layouts. — Expo Router docs
- Params and typed routes: Read dynamic values with
useLocalSearchParamsand navigate withrouter.push. Typed routes make wrong paths a compile error, which protects you from agent typos. — Expo Router docs - Protected routes: Redirect signed-out users to a login screen from a layout, or use the router's protected-route support in recent versions. Keep the auth check in one place. — Expo Router authentication
- Lists done right: Use
FlatListor Shopify'sFlashListfor long lists, give each row a stable key, and avoid rendering hundreds of views at once. — FlatList - Forms and the keyboard: Handle keyboard overlap, input focus order, validation messages and submit states. Use a form library such as React Hook Form with a schema validator like Zod if forms grow. — KeyboardAvoidingView
- Deep links: Links like
myapp://post/42or a universal link open a specific screen. Plan routes so every important screen has a stable path. — Expo linking
Concept videos
YouTube channels and searches for these topics. On a large screen they open in the reading panel next to the roadmap.
- Expo Router tutorials — Expo channel
- Expo Router full course — YouTube search: Expo Router tutorial tabs stack
- Galaxies.dev mobile tutorials — Simon Grimm channel
Explanation
Draw the navigation map first
Before prompting, write the route tree: tabs at the top, stacks inside each tab, modals on top. Paste it into your prompt so the agent creates files in the right folders.
One place for auth redirects
Scattering if (!user) router.replace('/login') across screens causes flicker and bugs. Put the check in a layout so every child screen is protected consistently.
Empty, loading, error
Every data screen has four states: loading, empty, error and content. Ask the agent to implement all four, not only the happy path.
What Is It?
Routing decides which screen shows for which URL-like path, and navigation moves the user between screens.
Expo Router maps files in app/ to routes automatically.
Why Should I Care?
A clear route tree makes agent output predictable and makes deep links, auth gates and analytics straightforward later.
Real World Analogy
Routes are the floor plan of a building: lobby (index), floors (tabs), rooms (stack screens) and a private office (modal). Visitors need signs (links) to find each room.
Visual Mental Model
app/
_layout.tsx (Stack)
(tabs)/_layout.tsx (Tabs)
index.tsx explore.tsx profile.tsx
post/[id].tsx
login.tsx (modal)Beginner Explanation
Create a tabs layout with Home, Explore and Profile, add one detail screen with a dynamic route, and ask your agent to add loading, empty and error states to every list.
Smallest Possible Example
import { Tabs } from 'expo-router';
export default function TabsLayout() {
return (
<Tabs screenOptions={{ headerShown: false }}>
<Tabs.Screen name="index" options={{ title: 'Home' }} />
<Tabs.Screen name="explore" options={{ title: 'Explore' }} />
<Tabs.Screen name="profile" options={{ title: 'Profile' }} />
</Tabs>
);
}Common Mistakes
❌ Putting data fetching and layout in one huge screen file.
Split into hooks and components so the agent edits small units.
❌ Using ScrollView with a long mapped list.
It renders everything at once. Use FlatList or FlashList.
❌ Hard-coding route strings everywhere.
Enable typed routes so mistakes are caught at compile time.
Real Project Example
Most Expo apps follow tabs-plus-stacks with a modal for create or sign-in flows; that pattern appears in Expo's own templates.
Build This Mini Project
Build a three-tab app with a detail route /item/[id], a login modal, and a redirect that sends signed-out users to login from the root layout.
Interview Question
How do you protect routes in Expo Router?
Check auth state in a shared layout and redirect or hide the protected group when the user is signed out, so every child screen inherits the protection.
Key Takeaways
- Write the route tree before prompting.
- Use layouts for tabs, stacks and auth checks.
- Use FlatList or FlashList for lists.
- Implement loading, empty and error states.
Stack for this step
| Layer | Pick | Why |
|---|---|---|
| Routing | Expo Router | File-based routes, typed paths, deep links. |
| Lists | FlatList / FlashList | Virtualised rendering. |
| Forms | React Hook Form + Zod | Validation and submit state. |
Prompts for Cursor, Claude Code & Codex
Paste these into Cursor, Claude Code, Codex, or any coding agent. Replace the bracketed parts with your app details, and keep the agent in plan mode first so you review the approach before it edits files.
Generate the route tree
From SPEC.md, propose an Expo Router route tree with tabs, stacks and modals. Output as a folder tree under app/ with one line per file describing its purpose. Do not create files yet.Build a screen with all states
Create app/(tabs)/explore.tsx that lists items from useItems(). Implement loading skeletons, an empty state with a call to action, an error state with retry, and the content list with FlatList. Use components/ui only.Auth gate
Add an auth gate in app/_layout.tsx: redirect to /login when there is no session, and to / after login. Keep the check in one place and avoid flicker by waiting for session loading.Claude Code skill for this step
Save this as .claude/skills/expo-router-screen/SKILL.md in your project so Claude Code loads it automatically when the task matches. The same text works as a Cursor rule or an AGENTS.md section.
---
name: expo-router-screen
description: Use when creating routes, layouts or navigation in the Expo Router app.
---
1. Check the route tree in SPEC.md before creating files.
2. Create the route file in the right folder and use typed routes for navigation.
3. Implement loading, empty, error and content states.
4. Add the screen to the showcase or test file and run typecheck and lint.Rules, databases & blogs to use
- Expo Router TypeScript rule: routing conventions
- React Native Expo rule: Expo app rules
- Mobile rules category: all mobile rules
- Top mobile apps: see navigation patterns in ranked apps
- AI chat app template: chat screen patterns
Resources
The 60-second story
Picture a building directory in a lobby. It lists every floor and room, and each room has a sign. You can walk straight to room 4B because the path is written down.
Expo Router makes the folder tree that directory. Create app/profile.tsx and the sign /profile exists. Tabs are floors, stacks are corridors, modals are private offices. The auth check is the security desk in the lobby: one place, everyone passes it.
Mental model: your folder tree is the building directory.

