Expo Router v56 is the biggest shift to the library since it launched. We've forked the parts of React Navigation that Expo Router builds on, shipped streaming server-side rendering, and brought Android closer to feature parity with iOS through a new toolbar API and expanded Native Tabs.
The fork is the headline change, and it's worth explaining first because it touches every Expo Router app. After that we'll walk through the new SSR APIs, the Android toolbar, and what's new in Native Tabs.
Why did we decide to fork React Navigation?
Expo has a long history with React Navigation. Brent Vatne, the longest tenured Expo employee and our VP of Engineering, led the project through the 1.0 and 2.0 releases, working alongside @ericvicenti and @satya164. Expo helped grow React Navigation from an early idea, shaped by React Native’s old NavigationExperimental API and Expo’s own ex-navigation, into the standard navigation library for the React Native ecosystem. Today, it remains one of the ecosystem’s core navigation solutions, alongside Expo Router.
React Navigation is now in Satya’s very capable hands, while our work in the navigation space has increasingly centered on Expo Router. As Expo Router has grown, we’ve found ourselves needing deeper control over the React Navigation internals that Expo Router builds on top of. We spoke with Satya and agreed that the best path forward for both projects was for Expo Router to fork the parts of React Navigation that it depends on most directly.
This was not a decision about moving away from React Navigation as a project. It was about giving each project the freedom to evolve in the direction that best serves its users.
For Expo Router, the fork gives us room to make changes that are specific to file-based routing, web, server rendering, and other Expo Router use cases. Some of the improvements we want to make would not necessarily apply to React Navigation users directly, and carrying those changes upstream would add complexity for everyone.
It also lets us create a more focused version of the React Navigation internals for direct use inside Expo Router. By owning that layer, we can simplify the integration, reduce the amount of workaround code, and make Expo Router easier to maintain over time.
Another practical reason is dependency versioning. In past releases, projects could end up with multiple versions of React Navigation installed, which led to issues. Forking the internal pieces we rely on gives us more control over compatibility and makes Expo Router releases more predictable.
Finally, Expo Router is improving its web-based capabilities such as data loaders and server-side rendering. These features are not part of React Navigation, and supporting them well requires changes that are much easier to make in a codebase tailored specifically to Expo Router.
What does it mean for you?
Because Expo Router no longer depends on React Navigation, you will no longer be able to use code imported directly from @react-navigation/*. We know that this is a breaking change for you, so we prepared several tools to make the migration easier.
To migrate all React Navigation imports to expo-router/react-navigation in your codebase, you can use our codemod:
- npx expo-codemod sdk-56-expo-router-react-navigation-replace srcOur migration guide contains all the necessary steps if you decide to do the migration manually. Lastly, in order to make the migration gradual and smooth, all imports of @react-navigation/core from libraries will be automatically replaced with expo-router/react-navigation ones for at least one release cycle.
If you have any problems or spot any issues, please let us know!
What’s next for Expo Router?
Together with the React Navigation team, we’re currently working on a shared API for library authors, to support both libraries at the same time.
If you maintain a library that should support both Expo Router and React Navigation, we’d love to hear from you and collaborate on adapting it to the new APIs.
Suspense customization in Expo Router
We’ve enabled support for customizing the Suspense fallback for routes within a _layout. You can export a SuspenseFallback to customize the loading screen.
import { ActivityIndicator, View } from 'react-native';import { Stack } from 'expo-router';export function SuspenseFallback() {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><ActivityIndicator size="large" /></View>);}export default function Layout() {return <Stack />;}
Server-side rendering in Expo Router
In addition to the server features already available, including API routes, middleware, data loaders, and static rendering, this release also introduces streaming server-side rendering, which helps improve perceived performance by allowing you to prioritize critical UI elements to appear before slower, data-dependent UI:
Using it is simple: just set unstable_useServerRendering to true in the Expo Router config options in your app config.
As part of streaming SSR, we also introduced a new way of generating HTML metadata for your routes by using a generateMetadata function.
We’ve also introduced helper utilities to make it easier to build type-safe data loaders: createStaticLoader, createServerLoader.
Android toolbar
In SDK 55, we added support for the toolbar on iOS. In this release, we added an equivalent feature on Android, bringing cross-platform compatibility. Much like iOS, you can place the Android toolbar in three placements: left, right, and bottom.
Check all the available options in toolbar documentation.
Native Tabs
Last Fall, in Router v6 (we changed our Router naming convention since then), we added support for the Native Tabs component. We’re actively working toward full support across all platforms and aim to mark the API as stable in the next release.
Expo Router v56 adds several new options to Native Tabs. One of the most demanded features is the way to prevent tabs from being selected. Starting with this release you can use the disabled property to display the tab in the tab-bar, but prevent users from clicking on it.
Check all the available options and platform support in the native tabs reference page.
Where to start with Expo Router v56
If you take nothing else away from this post, we hope you walk away feeling excited about these three updates:
- The React Navigation fork means a one-time import update for every Expo Router app. We've shipped a codemod and a compatibility layer so the migration is as easy as can be.
- Streaming SSR,
generateMetadata, and the new loader helpers help you build better Expo Router for Web experiences. - Android now has toolbar support and an expanded Native Tabs API, bringing it to parity with iOS.
If you're upgrading an existing app, start with the migration guide and run the codemod. If you're starting a new project, you'll get all of this by default in SDK 56.
We're on Discord and GitHub and we’d like to hear from you. Let us know what you build, and tell us when something breaks.


