Skip to main content

Create a Blank Stack Navigator

Start with a basic stack navigator using createBlankStackNavigator:
import { createBlankStackNavigator } from "react-native-screen-transitions/blank-stack";
import { NavigationContainer } from "@react-navigation/native";
import { View, Text, TouchableOpacity } from "react-native";

const Stack = createBlankStackNavigator();

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <TouchableOpacity
        onPress={() => navigation.navigate("Detail")}
        style={{
          paddingHorizontal: 20,
          paddingVertical: 12,
          backgroundColor: "#007AFF",
          borderRadius: 8,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 16 }}>Open Detail</Text>
      </TouchableOpacity>
    </View>
  );
}

function DetailScreen() {
  return (
    <View style={{ flex: 1, backgroundColor: "#fff", justifyContent: "center" }}>
      <Text>Detail Screen</Text>
    </View>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Detail" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
This creates a basic stack with no animations. Now let’s add a transition.

Add a Preset Animation

The library includes several presets for common animations. Use them in screen options:
import Transition from "react-native-screen-transitions";

<Stack.Screen
  name="Detail"
  component={DetailScreen}
  options={{
    ...Transition.Presets.SlideFromBottom(),
  }}
/>

Common Presets

PresetBehaviorBest For
SlideFromBottom()Slides up with fade inModal dialogs
SlideFromRight()Slides in from right edgeDetail/drill-down
FadeIn()Simple opacity fadeOverlay screens
ZoomIn()Scale + fade from centerImage detail views
SharedIGImage()Masked reveal (bounds)Image transitions
SharedAppleMusic()Complex shared elementAlbum to player

Enable Gestures

Add swipe-to-dismiss by enabling the gesture:
options={{
  ...Transition.Presets.SlideFromBottom(),
  gestureEnabled: true,
  gestureDirection: "vertical",
}}
Now you can swipe down to dismiss the screen.

Full Example

Here’s a complete working example:
import { createBlankStackNavigator } from "react-native-screen-transitions/blank-stack";
import Transition from "react-native-screen-transitions";
import { NavigationContainer } from "@react-navigation/native";
import { View, Text, TouchableOpacity, ScrollView } from "react-native";

const Stack = createBlankStackNavigator();

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, paddingTop: 60, paddingHorizontal: 20 }}>
      <Text style={{ fontSize: 28, fontWeight: "bold", marginBottom: 20 }}>
        Home
      </Text>
      <TouchableOpacity
        onPress={() => navigation.navigate("Detail")}
        style={{
          paddingHorizontal: 20,
          paddingVertical: 12,
          backgroundColor: "#007AFF",
          borderRadius: 8,
          marginBottom: 12,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 16 }}>Slide from Bottom</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() => navigation.navigate("Profile")}
        style={{
          paddingHorizontal: 20,
          paddingVertical: 12,
          backgroundColor: "#34C759",
          borderRadius: 8,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 16 }}>Slide from Right</Text>
      </TouchableOpacity>
    </View>
  );
}

function DetailScreen({ navigation }) {
  return (
    <View style={{ flex: 1, backgroundColor: "#fff", paddingTop: 60 }}>
      <ScrollView style={{ flex: 1, paddingHorizontal: 20 }}>
        <Text style={{ fontSize: 24, fontWeight: "bold", marginBottom: 10 }}>
          Detail Screen
        </Text>
        <Text>Swipe down to dismiss</Text>
      </ScrollView>
      <TouchableOpacity
        onPress={() => navigation.goBack()}
        style={{
          marginBottom: 20,
          marginHorizontal: 20,
          paddingVertical: 12,
          backgroundColor: "#FF3B30",
          borderRadius: 8,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 16, textAlign: "center" }}>
          Close
        </Text>
      </TouchableOpacity>
    </View>
  );
}

function ProfileScreen({ navigation }) {
  return (
    <View style={{ flex: 1, backgroundColor: "#f5f5f5", paddingTop: 60 }}>
      <Text style={{ fontSize: 24, fontWeight: "bold", paddingHorizontal: 20 }}>
        Profile
      </Text>
      <TouchableOpacity
        onPress={() => navigation.goBack()}
        style={{
          margin: 20,
          paddingVertical: 12,
          backgroundColor: "#FF3B30",
          borderRadius: 8,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 16, textAlign: "center" }}>
          Back
        </Text>
      </TouchableOpacity>
    </View>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={{
            ...Transition.Presets.SlideFromBottom(),
            gestureEnabled: true,
            gestureDirection: "vertical",
          }}
        />
        <Stack.Screen
          name="Profile"
          component={ProfileScreen}
          options={{
            ...Transition.Presets.SlideFromRight(),
            gestureEnabled: true,
            gestureDirection: "horizontal",
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

What’s Next?

  • Customize animations — Learn the progress model to write your own interpolators
  • Add gestures — Read Gestures for detailed configuration
  • Build sheets — Check Snap Points for bottom and side sheets
  • Animate shared elements — See Shared Elements for bounds-based animations