Navigation decision report · as of 31 October 2026

Expo UI vs React Navigation for Expo app navigation

What does "use Expo UI for navigation" mean today, how does it compare with React Navigation and Expo Router, and which should you choose? Every material claim links to a primary source (Expo or React Navigation docs, changelogs, source code and issues).

TL;DR

Premise check: "React Navigation (including Expo Router, which is built on it)" was true up to SDK 55. Since Expo Router v56, app code can no longer import @react-navigation/* inside an Expo Router app. A codemod rewrites those imports to expo-router/react-navigation and related paths.8,10 expo-router@58's npm dependencies no longer include the React Navigation packages.2 Expo says its "focus in the navigation space has shifted towards Expo Router", and that React Navigation still works in Expo projects.11

The three things being compared

Expo UI navigation containers

NavigationStack · NavigationSplitView · TabView · Toolbar inside one <Host> (SwiftUI) iOS / tvOS only · state-driven

Component-level UI with real SwiftUI containers. It doesn't know about routes.

Expo Router 58

file routes · deep links · typed routes beta Stack · NativeTabs stable · Stack.Toolbar forked RN core → react-native-screens

Expo's app-level navigation. iOS, Android and web.

React Navigation 7.x

static or dynamic config · linking config native-stack · tabs · drawer · top tabs @react-navigation/* → react-native-screens 4.x

Library-level navigation, configured in code. iOS, Android and web.

What "Expo UI for navigation" concretely is today

@expo/ui renders real SwiftUI and Jetpack Compose components from React. Each tree sits inside a Host.12 The SwiftUI and Compose APIs have been stable since SDK 56. The cross-platform "Universal" components run on web as experimental.13,11

Navigation pieceIn @expo/ui 58?Notes
NavigationStack / NavigationLink / NavigationDestinationYes, iOS new in 58.0.0Controlled by path/onPathChange. Content presented from the stack (sheet, popover) needs its own stack.5,14
NavigationSplitView (2–3 columns)Yes, iOS new in 58.0.3Collapses to one column on narrow windows. iOS 16+.6,14
TabView (incl. sidebarAdaptable)Yes, iOSThe docs say: "For routed bottom-tab navigation across full-screen routes, use expo-router/native-tabs instead."15
Toolbar, navigationTitle, searchableYes, iOSsearchable arrived in 58.0.15.14,i1
Sheets, menus, listsYesBottomSheet with detents, Menu, ContextMenu, Popover, List, Picker (iOS); ModalBottomSheet (Android).12,7
Android stack / NavHost / railNoCompose offers NavigationBar, TopAppBar, SearchBar and a floating toolbar, with no navigation container.7
Routes, URLs, deep linksNoNothing in the docs connects these containers to Expo Router or linking.5

Bottom line: Expo UI gives you native SwiftUI navigation containers for part of a screen on iOS, not an app-wide, cross-platform, URL-addressable navigation system. No Expo source presents it as a replacement for Expo Router or React Navigation. The Expo UI stable announcement positions it for "settings, modals, pickers, sheets" that should look like the OS.13

Side-by-side comparison

DimensionExpo UI containersExpo Router 58 (native)React Navigation 7.x
Maturity & stability Library stable since SDK 56, but the navigation containers only landed in Sept 2026 (58.0.x).14 Native tabs and Stack.Toolbar stable in SDK 58. SplitView, ExperimentalStack and zoom transitions are alpha.9,16,17 7.0 shipped Nov 2024, now 7.5.1. Native bottom tabs are unstable. 8.0 is alpha.51 with no beta date.3,18,19
Platform coverage iOS/tvOS only. Android has chrome only; web has no navigation containers.5,7 iOS, Android, web. Native tabs fall back to a basic layout on web, and Android allows at most 5 tabs.9 iOS, Android, web. Web "works best with fully client-side rendered apps". Native tabs have no web support.20,18
iPad / large screens Real NavigationSplitView and sidebarAdaptable TabView. These are the strongest iPad primitives, but iOS-only and unrouted.6,15 Tab bar can move to the top, with a sidebar via sidebarAdaptable (iOS 18+). A routed split view exists only as alpha SplitView, root-only.21,16 Native tabs tabBarControllerMode: 'tabSidebar' (iOS 18+, unstable). drawerType: 'permanent' for wide screens.18,22
Native look & feel These are SwiftUI views, so Liquid Glass, toolbars, titles and search come from the OS itself.12 Liquid Glass tab bar, minimize-on-scroll (iOS 26+), search tab (iOS 26.1+), large titles, Stack.SearchBar, form sheets, Link previews (iOS).9,23,24 Native stack uses UINavigationController/Fragment, with large titles, search bar (iOS 26 integrated) and Liquid Glass header options. Header items are unstable_.25
Stack / tab / drawer / modal coverage Stack, split and tabs on iOS. Sheets and popovers. No drawer.12 Stack, NativeTabs, JS tabs, Drawer layout, modals and form sheets.10,26 Broadest: native and JS stack, tabs, native tabs (unstable), drawer, material top tabs, form sheets with detents.25,27
Deep linking & typed routes None. You map URLs to path state yourself.5 Automatic deep link for every file route. Typed routes beta, off by default.28,29 Static API gives automatic types (StaticParamList) and linking={{enabled:'auto'}}. Dynamic API uses a manual linking config.30,31
Gestures & transitions Whatever SwiftUI's NavigationStack does natively (inference; not separately documented). Native stack transitions. Link.AppleZoom alpha, iOS 18+.17 Fixed native-stack animations. JS stack is fully customizable. Shared elements are experimental. No Android predictive back.27,32,33
Performance Native containers, but React Native content hosted inside SwiftUI has open bugs (blank in List, resize snapping).i2,i3 Native tabs render all tabs up front and have limited FlatList support.9 Docs recommend native-stack over JS stack. Tabs are lazy by default; freezeOnBlur is opt-in.27,34 Neither project publishes head-to-head benchmarks.
Interop & migration Drop into any screen of either system with <Host>. Nesting its NavigationStack inside a Router/RN stack screen is undocumented (double nav bars risk), so test it on a device. From RN: official guide maps navigators to _layout files. It doesn't support independent containers, initialState or non-serializable params.35 Pre-56 apps need the import codemod.10 Existing apps stay put. 8.0 will need React 19, RN 0.83, SDK 55+ and gesture-handler 3.19
Ecosystem (npm, wk of 23–29 Oct 2026) 6.76M/wk, inflated because expo-router 56–58 depends on it (inference).36 10.52M/wk.36 7.40M/wk for @react-navigation/native. 24.5k GitHub stars.36,37

Known gaps and open issues (sample)

AreaIssue
Expo UIexpo#52692: React Native views in a SwiftUI List go blank · expo#52396: hosted RN content snaps during SwiftUI resize animations
Expo Router native tabsexpo#52654: changing role on a mounted tab crashes (iOS 26.1+) · expo#43660: selectedStyle ignored on iPad · expo#51794: Stack.Protected drops the tab · expo#51740: cross-tab form sheet stuck · expo#52397: redirect to group tab renders blank. Documented limits: no nested native tabs and no runtime add/remove of tabs.9
React Navigation (iOS 26 / iPad)#13067: headerTitle ignores headerRight · #12932: headerTintColor broken · #12908: native tab labels truncated · #13262: tab bar disappears after rotation · #12843: iPad scrolls to top on back
Shared (react-native-screens)screens#5003: Liquid Glass header items jump instead of morphing · screens#4769: formSheet ScrollView sizing. Both Expo Router and React Navigation sit on this layer.

Recommendation

Default: Expo Router shell + Expo UI inside screens

  • App navigation in Expo Router SDK 58: Stack for pushes and sheets, NativeTabs (stable) for the Liquid Glass tab bar, iPad sidebar and search tab.9
  • You get deep links for free, plus web and one codebase for iOS and Android.28
  • Use @expo/ui for native controls and, on iOS, for contained sub-flows (settings, a split-view browser inside one tab). This matches Expo's own TabView guidance.15
  • Avoid alpha pieces (SplitView, ExperimentalStack, zoom) in production paths.16

When the other choice wins

  • React Navigation 7: you have an existing RN app, a brownfield app, dynamic or conditional navigator trees, independent containers, non-serializable params, or material top tabs. It's also the choice when you need configuration in code rather than files.35,27
  • Expo UI navigation containers as the main structure: only for an iOS/iPadOS-only app that wants real SwiftUI NavigationSplitView behavior and accepts building URL handling and Android navigation itself. Expect to write custom native modules for anything Expo UI doesn't expose (e.g. tab sections).
  • Wait for React Navigation 8 only if you need its inferred types, native tabs by default and SSR, and can tolerate an alpha.19

Decision table

Your situationChoose
New Expo app, iOS + Android (+ web)Expo Router 58 with NativeTabs and Stack; @expo/ui inside screens
Want Liquid Glass tab bar and iPad sidebar, production-ready todayExpo Router NativeTabs (stable) over RN 7 native tabs (unstable)
Existing React Navigation 7 app, working wellStay on React Navigation 7; add @expo/ui components where native UI helps
Existing Expo Router ≤55 appUpgrade along Expo Router; run the SDK 56 import codemod
iPad-only app needing a true multi-column splitExpo UI NavigationSplitView inside a Router screen (prototype first), or wait for Router SplitView to leave alpha
Android-first or Android parity requiredNot Expo UI for navigation; use Expo Router or React Navigation
Deep links and typed URLs are coreExpo Router (automatic links) or RN 7 static API, never Expo UI alone

Sources

  1. Expo SDK 58 changelog
  2. npm registry: expo-router 58.0.29 · SDK 58 bundledNativeModules.json
  3. React Navigation releases · React Navigation 7.0 blog
  4. react-native-screens 4.30.1
  5. Expo UI NavigationStack
  6. Expo UI NavigationSplitView
  7. Expo UI Jetpack Compose · Compose source (sdk-58)
  8. Expo Router v56: decoupling from React Navigation
  9. Expo Router native tabs guide
  10. Expo Router migration: SDK 55 → 56
  11. Expo SDK 56 changelog
  12. Expo UI overview · SwiftUI exports (sdk-58)
  13. Expo UI is stable (SDK 56)
  14. @expo/ui CHANGELOG (sdk-58)
  15. Expo UI TabView
  16. Expo Router SplitView (alpha) · ExperimentalStack (alpha)
  17. Expo Router zoom transition (alpha)
  18. React Navigation native bottom tabs
  19. React Navigation 8.0 alpha · 8.0 July progress
  20. React Navigation web support
  21. Expo Router NativeTabs API reference
  22. React Navigation drawer
  23. Expo Router Stack API · Stack.Toolbar · Modals & form sheets
  24. Expo Router Link preview
  25. React Navigation native stack
  26. Expo Router introduction
  27. React Navigation stack · material top tabs
  28. Expo Router static rendering · introduction
  29. Expo Router typed routes (beta)
  30. React Navigation static configuration · getting started
  31. React Navigation TypeScript · deep linking
  32. React Navigation shared element transitions
  33. React Navigation getting started (predictive back note)
  34. React Navigation bottom tabs
  35. Expo Router: migrate from React Navigation
  36. npm weekly downloads: expo-router · @react-navigation/native · @expo/ui
  37. react-navigation/react-navigation on GitHub
  38. expo#50346: searchable request, closed by 58.0.15