Guides

Expo Router

Use the blank stack Expo Router adapter inside Expo Router layouts.

Overview

Expo Router integration uses the package's Expo Router adapter. It is built on Expo Router's standard navigator APIs, so route layouts can import BlankStack directly.

Most work should use blank stack. Reach for native stack only when you specifically need @react-navigation/native-stack.

Blank Stack Layout

This is the pattern from the e2e app:

TSX

1// layouts/blank-stack.tsx
2import "react-native-reanimated";
3
4export { BlankStack } from "react-native-screen-transitions/expo-router";

This adapter lets your screens use screen options like screenStyleInterpolator, gestureEnabled, snapPoints, and overlay.

The blank-stack navigator itself also accepts navigator props like independent and enableNativeScreens.

Using It In Route Layouts

TSX

1// app/gestures/_layout.tsx
2import Transition from "react-native-screen-transitions";
3import { BlankStack } from "@/layouts/blank-stack";
4
5export default function GesturesLayout() {
6 return (
7 <BlankStack>
8 <BlankStack.Screen name="index" />
9 <BlankStack.Screen
10 name="sheet"
11 options={{
12 ...Transition.Presets.SlideFromBottom(),
13 }}
14 />
15 </BlankStack>
16 );
17}

router.push(), router.replace(), and router.back() still work normally. The transition behavior comes from the options you put on BlankStack.Screen.

Bounds And Router Navigation

TSX

1import { router } from "expo-router";
2import Transition from "react-native-screen-transitions";
3
4<Transition.Boundary
5 id="hero"
6 onPress={() => router.push("/detail")}
7>
8 <Card />
9</Transition.Boundary>

The destination can use a matching passive Transition.Boundary, Transition.Boundary.Target, navigationMaskEnabled, and screenStyleInterpolator the same way it would outside Expo Router.

Embedded Flows

TSX

1<BlankStack independent enableNativeScreens={false}>
2 <BlankStack.Screen name="index" />
3</BlankStack>

Use independent only when you want an isolated navigation tree, not for normal route layouts.