Skip to main content
Each stack type in react-native-screen-transitions extends the base ScreenTransitionConfig with stack-specific options. All three stacks share the same animation API but offer different integration approaches.

Stack Types Overview

Blank Stack

Full control, all features. Best for most apps.

Native Stack

Native screen primitives with custom animations.

Component Stack

Experimental. Embedded flows, isolated from React Navigation.

Blank Stack Options

BlankStackNavigationOptions extends ScreenTransitionConfig with blank-stack-specific options.
import { createBlankStackNavigator } from "react-native-screen-transitions/blank-stack";

const Stack = createBlankStackNavigator();

Type Definition

type BlankStackNavigationOptions = ScreenTransitionConfig & {
  detachPreviousScreen?: boolean;
  freezeOnBlur?: boolean;
};

Additional Properties

detachPreviousScreen
boolean
Whether to detach the previous screen from the view hierarchy to save memory.Set to false if you need the previous screen to be seen through the active screen (e.g., for transparent backgrounds).Only applicable if detachInactiveScreens isn’t set to false on the Navigator.
freezeOnBlur
boolean
Whether inactive screens should be suspended from re-rendering.Defaults to false unless enableFreeze() is run at the top of the application.Requires react-native-screens version >=3.16.0.Platform: iOS and Android only

Usage Example

import { createBlankStackNavigator } from "react-native-screen-transitions/blank-stack";
import Transition from "react-native-screen-transitions";

const Stack = createBlankStackNavigator();

function App() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen
        name="Modal"
        component={ModalScreen}
        options={{
          ...Transition.Presets.SlideFromBottom(),
          detachPreviousScreen: false, // Keep previous screen visible
          freezeOnBlur: true,          // Freeze when not focused
        }}
      />
    </Stack.Navigator>
  );
}

Native Stack Options

NativeStackNavigationOptions extends ScreenTransitionConfig with native stack capabilities and all native header options.
import { createNativeStackNavigator } from "react-native-screen-transitions/native-stack";

const Stack = createNativeStackNavigator();

Type Definition

type NativeStackNavigationOptions = ScreenTransitionConfig & {
  enableTransitions?: boolean;
  // Plus all native header options (title, headerShown, etc.)
};

Key Property

enableTransitions
boolean
required
Must be set to true to enable custom transitions.Sets presentation to containedTransparentModal, animation to none, and headerShown to false.
Without this, custom transitions won’t work. The Native Stack uses transparent modal presentation to intercept transitions.

Native Header Options

Native Stack includes all standard React Navigation native stack options:

Usage Example

import { createNativeStackNavigator } from "react-native-screen-transitions/native-stack";
import Transition from "react-native-screen-transitions";

const Stack = createNativeStackNavigator();

function App() {
  return (
    <Stack.Navigator>
      <Stack.Screen 
        name="Home" 
        component={HomeScreen}
        options={{
          title: "Home",
          headerShown: true,
        }}
      />
      <Stack.Screen
        name="Detail"
        component={DetailScreen}
        options={{
          enableTransitions: true, // Required for custom transitions
          ...Transition.Presets.SlideFromBottom(),
        }}
      />
    </Stack.Navigator>
  );
}

Caveats

The Native Stack uses transparent modal presentation which has trade-offs:
  • Delayed touch events - Exiting screens may have briefly delayed touch response
  • beforeRemove listeners - Relies on navigation lifecycle events
  • Rapid navigation - Some edge cases with very fast navigation sequences
For most apps, Blank Stack avoids these issues entirely.

Component Stack Options

Experimental: This API may change based on community feedback.
ComponentStackNavigationOptions extends ScreenTransitionConfig for standalone, embedded navigation flows.
import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";

const Stack = createComponentStackNavigator();

Type Definition

type ComponentStackNavigationOptions = ScreenTransitionConfig & {
  detachPreviousScreen?: boolean;
};

Additional Properties

detachPreviousScreen
boolean
Whether to detach the previous screen from the view hierarchy to save memory.Set to false if you need the previous screen visible through the active screen.

Usage Example

import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";
import Transition from "react-native-screen-transitions";

const Stack = createComponentStackNavigator();

function OnboardingFlow() {
  return (
    <Stack.Navigator initialRouteName="step1">
      <Stack.Screen 
        name="step1" 
        component={Step1}
        options={{
          ...Transition.Presets.SlideFromRight(),
        }}
      />
      <Stack.Screen 
        name="step2" 
        component={Step2}
        options={{
          ...Transition.Presets.SlideFromRight(),
        }}
      />
    </Stack.Navigator>
  );
}

Characteristics

  • No deep linking - Routes aren’t part of URL structure
  • Isolated state - Doesn’t affect parent navigation
  • Touch pass-through - Uses pointerEvents="box-none" by default
  • Embedded flows - Ideal for onboarding, wizards, etc.

Shared Configuration

All stack types support the full ScreenTransitionConfig API:

Animation

options={{
  screenStyleInterpolator: ({ progress, layouts: { screen } }) => {
    "worklet";
    return {
      contentStyle: {
        transform: [{
          translateY: interpolate(progress, [0, 1], [screen.height, 0])
        }]
      }
    };
  },
  transitionSpec: {
    open: { stiffness: 1000, damping: 500, mass: 3 },
    close: { stiffness: 1000, damping: 500, mass: 3 },
  }
}}

Gestures

options={{
  gestureEnabled: true,
  gestureDirection: "vertical",
  gestureVelocityImpact: 0.3,
  gestureActivationArea: "edge",
}}

Snap Points

options={{
  snapPoints: [0.5, 1.0],
  initialSnapIndex: 0,
  expandViaScrollView: true,
  backdropBehavior: "dismiss",
}}

Overlays

options={{
  overlay: ({ focusedIndex, progress }) => (
    <TabBar activeIndex={focusedIndex} progress={progress} />
  ),
  overlayShown: true,
}}

Comparison Table

FeatureBlank StackNative StackComponent Stack
Custom animations
Shared elements
Snap points
Gestures
Native headers
Deep linking
Isolated state
Performance⚡ Fast⚡ Fast⚡ Fast
Setup complexityLowMediumLow

TypeScript Helpers

Each stack provides TypeScript helpers for type-safe navigation:

Blank Stack

import type {
  BlankStackNavigationProp,
  BlankStackScreenProps,
} from "react-native-screen-transitions/blank-stack";

type RootStackParamList = {
  Home: undefined;
  Detail: { id: string };
};

type DetailScreenProps = BlankStackScreenProps<RootStackParamList, "Detail">;

function DetailScreen({ route, navigation }: DetailScreenProps) {
  const { id } = route.params;
  // ...
}

Native Stack

import type {
  NativeStackNavigationProp,
  NativeStackScreenProps,
} from "react-native-screen-transitions/native-stack";

type RootStackParamList = {
  Home: undefined;
  Detail: { id: string };
};

type DetailScreenProps = NativeStackScreenProps<RootStackParamList, "Detail">;

function DetailScreen({ route, navigation }: DetailScreenProps) {
  const { id } = route.params;
  // ...
}

Component Stack

import type {
  ComponentStackNavigationProp,
  ComponentStackScreenProps,
} from "react-native-screen-transitions/component-stack";

type OnboardingParamList = {
  step1: undefined;
  step2: { fromStep: number };
};

type Step2Props = ComponentStackScreenProps<OnboardingParamList, "step2">;

function Step2({ route, navigation }: Step2Props) {
  const { fromStep } = route.params;
  // ...
}