Expo Router v6: A new era of native feel for React developers

Product6 minutes read

Evan Bacon

Evan Bacon

Engineering

Expo Router v6 brings native iOS link previews, menus, liquid glass tabs, improved modals, and server middleware for next-level apps.

Introducing Expo Router v6: native feel, React-first simplicity

Expo Router v6 is here, and it's all about capturing that iconic native feel. We're exposing complex native APIs through clever React-first abstractions that just work™. Plus, we're bringing more server features to help you handle more advanced web cases.

Link previews

Mobile screens demand intuitive controls. That's why we're introducing <Link.Preview> and <Link.Menu> for Apple platforms, bringing long-press context menus, link previews, and seamless transitions directly to your Expo Router iOS apps.

Code
<Link>
<Link.Trigger><Card /></Link.Trigger>
<Link.Preview />
<Link.Menu>
<Link.MenuAction title="Share" onPress={share} />
</Link.Menu>
</Link>

No extra imports needed. Just wrap your existing Link components with <Link.Trigger> and add the new <Link.Preview /> component to create quick previews on long-press.

Quick Previews

You can also nest Links for different interactive zones, with custom views for advanced previews such as playing videos when long pressing thumbnails.

Try a long press!
Code
<Link.Preview>
<Video
className="flex-1 object-cover"
src={new URL("/superman-clip.mp4", location.href).href}
/>
</Link.Preview>

The menu system exposes UIContextMenuInteraction APIs on Apple platforms, supporting nested menus, SF Icons, toggles, and advanced features like keeping menus open after interaction. It's the same delightful experience users expect from native iOS apps, now in your React code.

Link menus

Context menus support a number of different features such as SF symbols, toggles, staying presented after tapping, and nesting submenus. We love context menus and will continue finding new ways to integrate them throughout the framework.

Native Tabs: Liquid Glass era

This features is in early beta and subject to breaking changes.
The liquid glass era is upon us

React Navigation historically used a universal TypeScript implementation of tabs, but in the era of liquid glass, native is the way.

Code
<NativeTabs>
<NativeTabs.Trigger name="(home)">
<Icon sf="star" />
<Label>New</Label>
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(messages)">
<Icon sf="bell" />
<Label>Messages</Label>
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(styles)">
<Icon sf="wand.and.rays" />
<Label>Styles</Label>
</NativeTabs.Trigger>
</NativeTabs>

The new tabs are marked unstable as we work out the perfect API, but you can try them today for native tabs on iOS and Android, with a new Radix-based web implementation that's more responsive.

NativeTabs introduce the concept of a Trigger for adding routes to a layout. Unlike a Screen which styles routes that are added automatically, this system gives you better control for hiding and removing tabs from the tab bar.

Native tabs on Apple platforms feature:

  • Bouncing transitions between routes
  • Automatic scroll-to-top behavior
  • iPad, tvOS, and desktop support

Native tabs on Android support:

  • Material themes
  • Improved keyboard support

Best practices for native tabs:

  • Use Apple SF Symbols for icons on iOS, Material design icons on Android, and Material or Lucide icons on web
  • Use platform colors for dynamic tints. The liquid glass updates automatically with dynamic iOS colors like PlatformColor("label") (black in light mode, white in dark mode)
  • Consider a custom web tab system using _layout.web.tsx while we improve the web fallback
  • Remove any custom "scroll to top" logic in favor of our first-class support in NativeTabs
  • You can still use JS <Tabs/> or headless tabs for more control over look and feel

More to come including better iPad support, more iOS 18 features, improved web support, and scroll-to-top on Android.

Liquid Glass Tabs with Expo Router v6 | Native Tabs

Modals on web

This feature is experimental. To use it, set the environment variable EXPO_UNSTABLE_WEB_MODAL=1

Modals on web now emulate the animations, gestures, and layouts of iPhone and iPad native modals. Using Radix and Vaul behind the scenes, they can be pulled down to dismiss.

Code
<Stack.Screen
name="movie/[movie]"
options={{ presentation: "modal" }}
/>

Desktop gets the same treatment as iPad, creating a consistent experience across all platforms. This is just the beginning of our modal improvements.

We've added:

  • Better desktop support using the same techniques as iPad
  • Form sheet support and detents for web modals
  • Native-feeling animations and gestures

More improvements to modals and form sheets coming in the future.

Server Middleware and Rewrites

Experimental support with more features coming as part of a larger effort to add full SSR for web.

Add app/+middleware.ts to define a server function that runs before server requests. Client-side navigation (native or web with <Link>) won't loop through the server. Learn more about middleware in the documentation.

Features:

  • Basic redirecting and authorization support
  • Runs at the edge with EAS Hosting (important since server middleware can slow down page response time)
  • Only run middleware on specific routes with matchers for HTTP methods and path patterns
  • Static rewrites config: https://docs.expo.dev/router/advanced/redirects/#rewrites
  • Redirects now support external URLs:
Code
{
"plugins": [
[
"expo-router",
{
"redirects": [
{
"source": "/x",
"destination": "https://x.com/expo"
}
]
}
]
]
}

Extra Improvements

  • Improved layout performance on heavy routes
  • Cleaner root layout: Sitemap and root +not-found moved to the virtual root navigator, reducing routes in app/_layout.tsx and making it easier to build custom navigators
  • Fewer warnings: Reduced react-native-web warnings in the default template (still one props.pointerEvents warning in React Navigation we've PR'd to remove)
  • Better error handling: Improved unhandled promise rejections for Splash Screen

Expo Router v6 makes apps more beautiful and native feeling while keeping the React-first APIs you love. Update today and start building experiences that truly feel at home on every platform.

And join the livestream on September 24th for live demos of Expo Router v6 and Q&A with the Router team:

Join the Expo Router livestream for Q&A with the team
Expo Router
SDK 54
Liquid Glass
Server Middleware
native tabs
autolinking

React Native CI/CD for Android, iOS, and Web

Learn more