Skip to main content
ScreenTransitionConfig is the core configuration type that defines how screens animate, respond to gestures, and behave during transitions. All three stack types (Blank Stack, Native Stack, and Component Stack) extend this type.

Type Definition

type ScreenTransitionConfig = {
  screenStyleInterpolator?: ScreenStyleInterpolator;
  transitionSpec?: TransitionSpec;
  gestureEnabled?: boolean;
  gestureDirection?: GestureDirection | GestureDirection[];
  gestureVelocityImpact?: number;
  snapVelocityImpact?: number;
  gestureResponseDistance?: number;
  gestureDrivesProgress?: boolean;
  gestureActivationArea?: GestureActivationArea;
  meta?: Record<string, unknown>;
  overlay?: (props: OverlayProps) => React.ReactNode;
  overlayMode?: OverlayMode;
  overlayShown?: boolean;
  experimental_enableHighRefreshRate?: boolean;
  snapPoints?: number[];
  initialSnapIndex?: number;
  expandViaScrollView?: boolean;
  gestureSnapLocked?: boolean;
  backdropBehavior?: "block" | "passthrough" | "dismiss" | "collapse";
  backdropComponent?: React.FC;
};

Properties

Animation Configuration

screenStyleInterpolator
ScreenStyleInterpolator
Function that calculates animated styles based on transition progress.Receives ScreenInterpolationProps and returns styles for screen elements.
transitionSpec
TransitionSpec
Animation configurations for different transition types.

Gesture Configuration

gestureEnabled
boolean
Controls whether swipe-to-dismiss is enabled.For screens with snapPoints, gesture-driven snapping between non-dismiss snap points remains available even when this is false.
gestureDirection
GestureDirection | GestureDirection[]
The direction(s) for the swipe gesture used to dismiss the screen.Values:
  • "horizontal" - Swipe left to dismiss
  • "horizontal-inverted" - Swipe right to dismiss
  • "vertical" - Swipe down to dismiss
  • "vertical-inverted" - Swipe up to dismiss
  • "bidirectional" - Any direction
  • Array of directions - Multiple directions (e.g., ["horizontal", "vertical"])
gestureVelocityImpact
number
default:"0.3"
How much the gesture’s final velocity impacts the dismiss decision.Higher values make the gesture more responsive to flicks.
snapVelocityImpact
number
default:"0.1"
How much velocity affects snap point targeting.Lower values make snapping feel more deliberate (iOS-like), higher values make it more responsive to flicks.
gestureResponseDistance
number
Distance threshold (in pixels) for gesture recognition throughout the screen.
gestureDrivesProgress
boolean
Whether the gesture directly drives the animation progress.When true, the screen follows your finger. When false, the gesture triggers an animation.
gestureActivationArea
GestureActivationArea
The area of the screen where the gesture can be activated.Simple values:
  • "edge" - Only from screen edges
  • "screen" - Anywhere on screen
Per-side configuration:
gestureActivationArea: {
  left: "edge",
  right: "screen",
  top: "edge",
  bottom: "screen",
}

Snap Points

snapPoints
number[]
Array of fractions (0-1) where the screen can rest.Each value represents a fraction of the screen dimension in the gesture direction.
initialSnapIndex
number
default:"0"
The initial snap point index when the screen opens.
snapPoints: [0.5, 1.0]
initialSnapIndex: 0  // Opens at 50%
expandViaScrollView
boolean
default:"true"
Controls whether swiping to expand works from within a ScrollView.
  • true (Apple Maps style): Swiping up at scroll top expands the sheet
  • false (Instagram style): Expand only works via deadspace
Collapse (swipe down at scroll top) always works regardless of this setting.
gestureSnapLocked
boolean
default:"false"
Locks gesture-based snap movement to the current snap point.When enabled, users cannot gesture between snap points. Programmatic snapTo() calls still work. If dismiss gestures are allowed (gestureEnabled !== false), swipe-to-dismiss still works.

Backdrop Configuration

backdropBehavior
'block' | 'passthrough' | 'dismiss' | 'collapse'
default:"'block'"
Controls how touches interact with the backdrop area (outside screen content).
  • "block" - Backdrop catches all touches (default)
  • "passthrough" - Touches pass through to content behind
  • "dismiss" - Tapping backdrop dismisses the screen
  • "collapse" - Tapping backdrop collapses to next lower snap point, then dismisses
backdropComponent
React.FC
Custom component to render as the backdrop layer.When provided, replaces the default backdrop entirely — including press handling. You must handle dismissal inside your component using navigation methods.Use useScreenAnimation() inside the component to access animation values.

Overlay Configuration

overlay
(props: OverlayProps) => React.ReactNode
Function that returns a React Element to display as a persistent overlay.The overlay animates with the stack and receives navigation state and progress values.
overlayShown
boolean
Whether to show the overlay.The overlay is shown by default when overlay is provided. Set to false to hide it.
overlayMode
OverlayMode
Deprecated: This option is no longer needed. Overlays now always render as “float” mode (single persistent overlay above all screens).

Metadata

meta
Record<string, unknown>
Custom metadata passed through to animation props.Use this for conditional animation logic instead of checking route names.

Experimental

experimental_enableHighRefreshRate
boolean
default:"false"
Forces the display to run at maximum refresh rate during transitions.Prevents iOS/Android from throttling to 60fps. Useful for smoother animations on 90/120/144Hz displays.Note: Increases battery usage while active.

Usage Examples

Basic Transition

import { interpolate } from "react-native-reanimated";
import type { ScreenTransitionConfig } from "react-native-screen-transitions";

const config: ScreenTransitionConfig = {
  gestureEnabled: true,
  gestureDirection: "vertical",
  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 },
  }
};

Bottom Sheet with Snap Points

const sheetConfig: ScreenTransitionConfig = {
  gestureEnabled: true,
  gestureDirection: "vertical",
  snapPoints: [0.5, 1.0],
  initialSnapIndex: 0,
  backdropBehavior: "dismiss",
  screenStyleInterpolator: ({ progress, layouts: { screen } }) => {
    "worklet";
    return {
      contentStyle: {
        transform: [{
          translateY: interpolate(progress, [0, 1], [screen.height, 0])
        }]
      },
      backdropStyle: {
        backgroundColor: "black",
        opacity: interpolate(progress, [0, 1], [0, 0.5])
      }
    };
  },
};

Shared Element Transition

const sharedConfig: ScreenTransitionConfig = {
  gestureEnabled: true,
  gestureDirection: ["vertical", "horizontal"],
  gestureDrivesProgress: false,
  screenStyleInterpolator: ({ bounds, focused, progress }) => {
    "worklet";

    const boundValues = bounds({
      id: "avatar",
      method: focused ? "content" : "transform",
      scaleMode: "uniform",
      raw: true,
    });

    return {
      avatar: {
        transform: [
          { translateX: boundValues.translateX || 0 },
          { translateY: boundValues.translateY || 0 },
          { scaleX: boundValues.scaleX || 1 },
          { scaleY: boundValues.scaleY || 1 },
        ]
      }
    };
  },
};

Stack-Specific Extensions

Each stack type extends ScreenTransitionConfig with additional options:

Blank Stack

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

Native Stack

type NativeStackNavigationOptions = ScreenTransitionConfig & {
  enableTransitions?: boolean;
  // Plus all native header options
};

Component Stack

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