Expo Router just made its biggest change since launch. Version 56 forks from React Navigation, adds streaming server-side rendering, and gives Android developers the toolbar API they've been waiting for.
The fork is the big story here, affecting every Expo Router app. But there's more: new SSR capabilities, an Android toolbar that matches iOS, and expanded Native Tabs. Let's break down what changed and why it matters.
The React Navigation fork explained
Expo has deep roots with React Navigation. Brent Vatne, Expo's VP of Engineering, led React Navigation through versions 1.0 and 2.0 alongside @ericvicenti and @satya164. We helped React Navigation grow from an early experiment, influenced by React Native's NavigationExperimental and our own ex-navigation, into the standard navigation solution for React Native.
React Navigation remains in Satya's capable hands while our focus shifted to Expo Router. As Expo Router evolved, we needed deeper control over React Navigation's internals. After talking with Satya, we agreed that forking the pieces Expo Router depends on would serve both projects better.
This isn't about abandoning React Navigation. It's about giving each project room to grow in different directions.
For Expo Router, the fork opens space for changes specific to file-based routing, web features, and server rendering. Some improvements we want to make wouldn't help React Navigation users directly, and pushing those changes upstream would add unnecessary complexity.
We can now create a focused version of React Navigation's internals that works specifically for Expo Router. This lets us simplify integration, reduce workaround code, and make maintenance easier.
There's also a practical benefit: dependency versioning. Projects sometimes ended up with multiple React Navigation versions installed, causing conflicts. Forking the internal pieces gives us better control over compatibility and makes releases more predictable.
Expo Router's web capabilities like data loaders and server-side rendering need changes that are easier to make in a codebase built specifically for these features.
How the fork affects your code
Since Expo Router no longer depends on React Navigation, you can't import code directly from @react-navigation/* packages. We know this breaks existing code, so we built tools to help with migration.
Use our codemod to migrate all React Navigation imports to expo-router/react-navigation:
Our migration guide walks through manual migration steps. To ease the transition, imports of @react-navigation/core from libraries will automatically redirect to expo-router/react-navigation for at least one release cycle.
If you run into problems, let us know.
What's next for both projects
We're working with the React Navigation team on a shared API for library authors who need to support both libraries.
If you maintain a library that should work with both Expo Router and React Navigation, reach out. We'd like to collaborate on adapting it to the new APIs.
Custom Suspense fallbacks
You can now customize the Suspense fallback for routes within a _layout. Export a [SuspenseFallback](https://docs.expo.dev/router/error-handling/#loading-states-with-suspense-fallback) 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 />;
}
Streaming SSR arrives
Expo Router already supported API routes, middleware, data loaders, and static rendering. Version 56 adds streaming server-side rendering, which improves perceived performance by letting you prioritize important UI elements over slower, data-dependent components.
Enable it by setting unstable_useServerRendering to true in your Expo Router config.
Streaming SSR includes a new way to generate HTML metadata using a generateMetadata function.
We also added helper utilities for type-safe data loaders: [createStaticLoader](https://docs.expo.dev/versions/latest/sdk/server/#createstaticloaderfn) and [createServerLoader](https://docs.expo.dev/versions/latest/sdk/server/#createserverloaderfn).
Android gets the toolbar
SDK 55 brought toolbar support to iOS. Version 56 adds the same feature to Android, achieving cross-platform compatibility. Like iOS, you can place the Android toolbar in three positions: left, right, and bottom.
See all available options in the toolbar documentation.
Native Tabs expansion
Last fall, in Router v6 (we changed our Router naming convention since then), we added Native Tabs support. We're working toward full cross-platform support and plan to mark the API as stable in the next release.
Expo Router v56 adds new options to Native Tabs. The most requested feature was preventing tab selection. You can now use the disabled property to show a tab in the tab bar while preventing user interaction.
Check all available options and platform support in the Native Tabs reference page.
Getting started with v56
Three key takeaways from this release:
The React Navigation fork requires a one-time import update for every Expo Router app. Our codemod and compatibility layer make migration straightforward.
Streaming SSR, generateMetadata, and new loader helpers improve web experiences with Expo Router.
Android now has toolbar support and expanded Native Tabs, matching iOS feature parity.
For existing apps, start with the migration guide and run the codemod. New projects get all these features by default in SDK 56.
Find us on Discord and GitHub. We want to hear what you build and when something breaks.
This post is based on content from the Expo blog. Follow @expo for more React Native content.