Expo Router is the default navigation in Expo SDK 57 apps. File-based routes, native layouts, and typed params. Do not import @react-navigation/* in the application code — use the entry points of expo-router (default since SDK 56).
General app: react-native-development. UI: better-mobile-interface-react-native.
SDK 57 Baseline
| Item | Value |
|---|---|
| Expo | SDK 57 |
| React Native | 0.86 |
| React | 19.2.x |
| Node | 22.13+ recommended |
- Align deps with
npx expo install/expo install --fix. - Run
npx expo-doctorafter upgrade. - Preserve the existing
app/structure of the project.
Route structure
app/
_layout.tsx # root providers + Stack/Slot
index.tsx
(auth)/
_layout.tsx
login.tsx
(app)/
_layout.tsx # tabs ou stack autenticado
index.tsx
trip/[id].tsx
+not-found.tsx
- Folders
()group layout without a URL segment. [param]and[...slug]for dynamic ones._layout.tsxdefines the Stack / Tabs / Drawer for that level.
Imports (SDK 56+)
// Correto
import { Stack, Tabs, Link, useRouter, useLocalSearchParams } from 'expo-router';
import { ThemeProvider, DarkTheme } from 'expo-router/react-navigation';
// Evitar no app code
import { createNativeStackNavigator } from '@react-navigation/native-stack';
| Before | After |
|---|---|
@react-navigation/native |
expo-router/react-navigation |
@react-navigation/bottom-tabs |
expo-router/js-tabs or <Tabs> |
@react-navigation/native-stack |
<Stack> from expo-router |
Non-negotiable rules
- Type params (typed routes / project helpers); do not trust magic strings.
- Do not navigate during render — only in handlers/effects after an action.
- Separate auth vs app trees (redirect with
useSegments/Stack.Protected/ SDK default). - Deep links and scheme declared in
app.json/app.config. - Accessible headers/tabs; real titles and labels (not “Screen1”).
Stack, Tabs, Drawer
- Root: providers (SafeArea, theme, query) in the root
_layout. Stackfor linear flows (onboarding, trip detail).Tabsfor main destinations; badge via Expo Router APIs when necessary.Draweronly if the product already uses that pattern.- Modals:
presentation: 'modal'/ formSheet depending on platform.
Auth and guards
// Padrão: redirect se sessão ausente
const { user } = useAuth();
const segments = useSegments();
useEffect(() => {
const inAuth = segments[0] === '(auth)';
if (!user && !inAuth) router.replace('/(auth)/login');
if (user && inAuth) router.replace('/(app)');
}, [user, segments]);
- Session loading: splash/slot until auth hydrates — avoids flashing the wrong screen.
- Logout clears the sensitive stack.
Deep linking
- Single app scheme (
myapp://). - Universal Links / App Links with associated domains when in production.
- Test cold start and warm start with path + query.
- Invalid params → not-found or safe fallback.
Anti-patterns
- Importing
@react-navigation/*directly in the SDK 56/57 app - Multiple manual
NavigationContainerwith Expo Router router.pushin a loop without correct dependencies- Typed routes turned off “to go faster”
- Mixing classic React Navigation and Expo Router without a boundary
Completion criteria
- Layouts and routes aligned with SDK 57 / the project's current Expo Router
- Auth groups without incorrect flash
- Typed params in the flows touched
- Deep link of the main flow verified
- Imports only via
expo-router*