Architecture & Performance· 6 min read

Expo Router vs React Navigation in 2026: Which to Use and Why

Expo Router vs React Navigation in 2026: file-based routes vs config, deep links, web URLs, native tabs, what changed in SDK 56, and which to pick.

By

Full-Stack, Mobile & AI Engineer

Navigation is the skeleton of a mobile app: every screen hangs off it, every deep link lands in it, and changing it later touches everything. For years, React Navigation was the obvious choice. Then Expo Router arrived with file-based routing, automatic deep links and web URLs, and the question became which one to pick, and whether to move.

In 2026 the answer has also shifted underneath: with Expo SDK 56, Expo Router stopped depending on React Navigation and forked the parts it builds on. This guide compares Expo Router and React Navigation as they stand today, explains what that change means, and gives a clear recommendation for new and existing apps.

Key takeaways

  • Expo Router uses your file structure as your navigation: every file in app/ is a route, with deep links and web URLs automatically.
  • React Navigation uses configuration in code, and remains a solid, flexible choice, especially for bare and brownfield apps.
  • Since SDK 56, Expo Router no longer depends on React Navigation; most direct @react-navigation/* imports don't work with expo-router, and Expo provides a codemod.
  • For new Expo apps, Expo Router is the default and the better choice.
  • For existing React Navigation apps, migrate only when you gain something (web, deep links, consistency), not because of fashion.

How each one works

Expo Router maps files to routes:

app/
  _layout.tsx          // root stack
  (tabs)/
    _layout.tsx        // tab navigator
    index.tsx          // "/" home tab
    bookings.tsx       // "/bookings"
  class/
    [id].tsx           // "/class/123"
  settings.tsx         // "/settings"

Each layout file decides how its children are shown (stack, tabs, modal). Links use URLs: <Link href="/class/123">. Every route is automatically deep-linkable and, on the web, has a real URL.

React Navigation is configured in code: you create stack and tab navigators, register screens, and navigate by screen name. Version 7 added a static configuration API that brings type safety and automatic linking closer to what file-based routing offers.

Expo Router vs React Navigation at a glance

Expo RouterReact Navigation
Route definitionFiles and folders in app/Navigators configured in code
Deep linksAutomatic for every routeConfigured (simpler with the static API)
Web URLsBuilt in, with static or server renderingPossible, more setup
Typed routesGenerated from the file systemThrough TypeScript configuration
Native tabsNative system tabs, including Liquid Glass on iOS 26Through native-backed navigators
API routesYes (server endpoints alongside routes)No
Best forNew Expo apps, apps with web, deep-link-heavy appsBare and brownfield apps, very custom navigation

What changed in SDK 56

Expo Router was originally built on top of React Navigation. In SDK 56, Expo forked the parts of React Navigation that Expo Router builds around, so the router no longer depends on the React Navigation packages. The practical effects:

  • Code importing directly from @react-navigation/* inside an Expo Router app may stop working out of the box.
  • Expo provides a codemod (npx expo-codemod sdk-56-expo-router-react-navigation-replace) and a migration guide for the manual steps.
  • React Navigation itself continues as an independent library, and Expo offers a template for projects that prefer it.

If you upgrade an Expo Router app to SDK 56 or later, run the codemod first and then fix any remaining imports.

Common pitfalls with file-based routing

File-based routing is simple until a few patterns bite:

  • Auth gating. Don't scatter redirects across screens. Protect groups of routes in their layout (for example with protected stacks or a redirect in the group's _layout.tsx), so signed-out users can't reach them by deep link either.
  • Groups versus paths. Folders in parentheses, like (tabs), organise routes without adding to the URL. Mixing them up creates confusing paths and duplicate screens.
  • Heavy layouts. Layout files render around many screens. Keep data fetching and expensive work in screens, not layouts, or every navigation pays for it.
  • Params as strings. Route params arrive as strings; parse and validate them (for example with Zod) before using them as numbers or IDs.
  • Renaming files is renaming URLs. Moving a file changes its route, which can break shared links and notifications. Treat renames like API changes.

Expo Router how-tos people search for

Reading params. A route like app/bookings/[id].tsx reads its params with a hook:

const { id } = useLocalSearchParams<{ id: string }>();

Setting the anchor screen. To make sure deep-linked screens can navigate back to a sensible root, set an anchor in the layout. It replaces the deprecated initialRouteName:

export const unstable_settings = { anchor: "index" };

Tabs. A (tabs) group with a _layout.tsx that renders <Tabs /> gives you a tab bar whose screens are the files in that folder.

Sheets and modals. Set presentation in a stack screen's options (for example "modal" or "formSheet") to present a route as a modal or sheet.

Replacing without animation. router.replace("/home") swaps the current screen; set the target screen's animation option to "none" when you don't want a transition, for example after sign-in.

Styling. NativeWind and other styling libraries work normally inside Expo Router screens; routing and styling are independent.

When Expo Router isn't working

  • A route doesn't exist: check the file sits inside the app directory, has a default export, and isn't hidden by a group name you didn't intend.
  • Navigation goes to the wrong screen: look for two files resolving to the same path, often a group and a folder with the same name.
  • Back goes somewhere odd after a deep link: set an anchor in the parent layout.
  • Types complain about routes: restart the dev server so typed routes regenerate.

When to choose Expo Router

  • You're starting a new Expo app.
  • You want deep links, universal links and shareable URLs without maintaining a linking config.
  • You plan a web version of the app.
  • You like the predictability of "the file is the route" across a growing team.

When to stay with (or choose) React Navigation

  • Your app is bare React Native, or React Native embedded in a native app.
  • You have a large, working navigation setup and no reason to change it.
  • Your navigation is unusual enough that configuration in code is clearer than files.
From the field: I've shipped apps with Expo Router navigation and with React Navigation, on both Expo and bare workflows. For new Expo apps I'd choose Expo Router without hesitation; for an existing app with a stable React Navigation setup, I'd only migrate alongside a reason like adding a web version or overhauling deep links.

Migrating from React Navigation to Expo Router

If you decide to move:

  1. Map your navigators to layouts: each stack or tab navigator becomes a folder with a _layout.tsx.
  2. Move screens into route files, and turn route params into dynamic segments ([id].tsx).
  3. Replace navigation.navigate calls with router.push and <Link> using paths.
  4. Remove the manual linking config and test every deep link and universal link.
  5. Ship incrementally if the app is large: keep a working build at every step and test on both platforms.

FAQ

Is Expo Router better than React Navigation?

For new Expo apps, yes in most cases: routes come from files, deep links and web URLs are automatic, and native tabs are built in. React Navigation remains a strong choice for bare and brownfield apps or very custom navigation, and it's actively maintained.

Does Expo Router still use React Navigation?

Not since Expo SDK 56. Expo Router forked the parts of React Navigation it builds on, so it no longer depends on React Navigation packages. Code that imports directly from @react-navigation/* may need updating, using Expo's codemod and migration guide.

Can I use Expo Router without Expo?

Expo Router is part of the Expo ecosystem and expects an Expo project setup, but that includes bare projects using Expo modules. If you don't use Expo at all, React Navigation is the natural choice.

Every file in the app directory is a route with a path, so a link like yourapp://class/123 or a universal link to https://yourdomain.com/class/123 opens the matching screen automatically. You still configure the URL scheme and, for universal links, your domain association files.

Next steps

If you're choosing navigation for a new app, or weighing a move to Expo Router, I can help you decide and carry out the migration safely. Get in touch, or see how I work as a React Native developer.

Sources

Bhuwanesh Sisodia

Bhuwanesh Sisodia

Full-Stack, Mobile & AI Engineer

Bhuwanesh Sisodia is a Full-Stack, Mobile & AI Engineer based in Mumbai, with 7+ years of experience and 50+ apps shipped to the App Store and Google Play. He works independently with startups and product teams worldwide.

About meGitHubLinkedInX

Related