Expo Router brings file-based routing to React Native: your app/ directory is your navigation tree. Screens are files, layouts are _layout files, and every screen automatically gets a URL — which means deep links work on day one instead of being a launch-week scramble.
The mental model
app/
_layout.tsx → root layout (providers, theme)
index.tsx → "/"
(tabs)/
_layout.tsx → tab navigator
home.tsx → "/home"
profile.tsx → "/profile"
settings/
[section].tsx → "/settings/:section"
modal.tsx → presented modally via the root layout
Groups in parentheses organise without affecting the URL. Dynamic segments use brackets. Nested _layout files compose navigators — the tab bar lives in (tabs)/_layout.tsx, a stack wraps it from the root.
Typed routes
Enable typed routes and router.push("/settings/notifications") type-checks against the routes that actually exist — a whole class of navigation bugs gone at compile time:
import { Link } from "expo-router";
<Link href="/settings/notifications">Notifications</Link>
Migrating from React Navigation incrementally
Expo Router is built on React Navigation, which is what makes incremental migration practical:
- Mount your existing root navigator inside
app/_layout.tsx— everything works as before. - Move one navigator at a time into the file tree, leaves first (settings stacks and simple flows before the tab root).
- Replace
navigation.navigate(...)calls withrouter.push(...)/<Link>as each area moves. - Delete your hand-maintained linking config last — the file tree now is the linking config.
When React Navigation directly is still right
Brownfield apps embedded in native shells, apps with heavily dynamic runtime-defined navigation, or teams not on Expo tooling can reasonably stay on plain React Navigation. It remains excellent. But for a new Expo app in 2026, Expo Router is the default we recommend — you get URLs, typed navigation, and layout composition for free.