← Writing

25 Sept 2026 · 4 min read

Expo Router vs React Navigation: which to use for a new app in 2026

Expo Router is built on React Navigation, so this isn't really either-or. What each one is, how MeltsWell's Expo app is routed across 31 files, and when plain React Navigation still makes sense.

Short answer: for a new Expo app, use Expo Router. For an existing app that already runs on React Navigation and works, don't migrate for the sake of it.

The two aren't really competitors. Expo Router is built on top of React Navigation. The stacks, tabs and transitions are React Navigation underneath. What Expo Router changes is how you declare them: with files and folders instead of a navigator config.

We built the MeltsWell mobile app with Expo Router in August 2026. Here's what that looks like and where it helped.

What is Expo, and where React Native fits

React Native lets you write iOS and Android apps in React. Expo is the framework and toolchain around it: the SDK of native modules (camera, images, haptics, secure storage), the build service (EAS), over-the-air updates, and now the router. It's the default way to start a React Native app. The React Native docs recommend a framework, and Expo is the one they point to.

"Expo vs bare React Native" used to be a real trade-off, because Expo couldn't run custom native code. That ended years ago. With development builds you can add any native module, and MeltsWell does: we patch the Xcode build and write our own config plugins. You keep Expo's tooling either way.

Expo Router vs React Navigation at a glance

Expo RouterReact Navigation
How you define screensFiles in app/, one per screenNavigators and screens in code
Deep linksAutomatic, every file is a URLManual linking config
Typed routesGenerated from your filesYou write the param types
Web supportSame routes on web, real URLsPossible, more setup
Works outside ExpoNoYes
Underlying navigationReact NavigationReact Navigation
Best forNew Expo appsExisting apps, non-Expo projects, unusual navigation

How MeltsWell's app is routed

31 route files. The folder is the map of the app:

app/
  _layout.tsx            root stack: auth, fonts, query cache, splash
  (tabs)/
    _layout.tsx          4 tabs: Discover, MeltSwipe, Saved, Profile
    index.tsx            Discover
    meltswipe.tsx
    saved.tsx
    profile.tsx
  melter/[slug].tsx      a baker's page
  sell/
    _layout.tsx          the seller onboarding stack
    start.tsx
    identity-name.tsx
    menu-product.tsx
    go-live.tsx
    ... 17 more screens
  onboarding.tsx
  sign-in.tsx

Three things this gave us for free:

Deep links. melter/[slug].tsx means meltswell://melter/some-baker opens that baker's page, with no linking config to maintain. When a baker shares their page, the link can land in the app on the right screen.

Typed routes. With typedRoutes on, router.push("/melter/...") is checked by TypeScript. A renamed file breaks the build instead of breaking a button in production.

A 21-screen flow that stays readable. Seller onboarding in the app is its own folder with its own stack layout. Adding a step is adding a file. In a React Navigation config, a flow that size is a long list of <Stack.Screen> entries that you scroll past to find anything.

Native tabs

The tab bar uses Expo Router's native tabs. On iOS 26 you get the system Liquid Glass tab bar, and on Android you get Material 3, both from one component. On iOS versions before 26 the transparent bar let list rows show through the icons, so we give those versions a frosted bar instead. We found that one on a real iPhone 12, not in the simulator.

This is the kind of thing Expo Router gets first. Native tabs are still marked unstable, so pin your Expo version and read the changelog when you upgrade.

Where React Navigation is still the right call

Your app already uses it. Migrating means moving every screen into files and rewriting how you navigate. If users aren't feeling a problem, spend the week on the product.

You're not on Expo. Expo Router needs Expo. If your team runs a bare React Native setup with its own build pipeline, React Navigation is the router.

Navigation that doesn't map to URLs. Dynamic navigators built at runtime, or a structure driven by a server config. File-based routing assumes your screens are known at build time.

You want the lower-level control. Every React Navigation option is available through Expo Router, but when you're fighting an edge case it can help to own the navigator code directly.

What else is in the MeltsWell app

For anyone scoping an Expo app, the rest of the stack: Expo SDK 57, Clerk for sign-in, TanStack Query with an offline cache so saved bakers load without a connection, Zustand for local state, expo-image, Reanimated for animation, Sentry for crashes, and EAS for builds and over-the-air updates with separate preview and production channels.

The app talks to the same API as the website. That's why it had real screens on its first day, August 9: the backend and the design already existed. The story of how long the whole thing took is in how long it takes to build an app.

So which one?

  • New app, on Expo: Expo Router.
  • Existing app on React Navigation that works: stay.
  • Bare React Native, no Expo: React Navigation.
  • You want web and mobile from one codebase: Expo Router, because routes become real URLs on web.

If you're deciding between web and mobile first, or what the first version should include, MVP development for startups covers that. A mobile app with a backend costs $15,000 to $30,000 with us, and the cost calculator gives you a range for yours. Or tell us what you're building.

Written by Badr El Adraoui, founder of Node & Scale. Building something? Build with us.