Guides

Upgrading from v3

Move a Version 3 app to the current Screen Transitions architecture without rewriting its transitions.

Most transition code does not need to change. Presets, screen interpolators, gestures, overlays, snap points, and bounds keep the same model. Migration work is concentrated in dependencies, navigator imports, and APIs that were already deprecated in Version 3.

Before migrating

Version 3 remains available for apps that need React before 19.2, Reanimated 3, React Navigation 6, or an older Expo Router setup. Its peer floors are:

  • React: no package-level minimum
  • React Navigation: 6.0 or later
  • Native Stack: 7.0 or later
  • Reanimated: 3.16 or later, including 4.x
  • Gesture Handler: 2.16.1 or later
  • React Native Screens: 4.4 or later

Update the runtime

The current release requires React 19.2, Reanimated 4, Worklets 0.8, and React Navigation 7.3 or later. Expo Router requires 56.2.10 or later and remains an Alpha integration.

Replace navigator imports

For React Navigation, replace the Version 3 Blank Stack entry point:

TSX

1// Version 3
2import { createBlankStackNavigator } from "react-native-screen-transitions/blank-stack";
3
4// Current
5import { createBlankStackNavigator } from "react-native-screen-transitions/react-navigation";

Expo Router imports BlankStack from its own host entry point:

TSX

1import { BlankStack } from "react-native-screen-transitions/expo-router";

Version 3 has no Expo Router entry point. It wraps the Blank Stack navigator with Expo Router's withLayoutContext:

TSX

1import type {
2 ParamListBase,
3 StackNavigationState,
4} from "@react-navigation/native";
5import { withLayoutContext } from "expo-router";
6import type { ComponentProps } from "react";
7import {
8 type BlankStackNavigationEventMap,
9 type BlankStackNavigationOptions,
10 createBlankStackNavigator,
11} from "react-native-screen-transitions/blank-stack";
12
13const { Navigator } = createBlankStackNavigator();
14
15function BlankStackNavigator(props: ComponentProps<typeof Navigator>) {
16 return <Navigator {...props} />;
17}
18
19export const BlankStack = withLayoutContext<
20 BlankStackNavigationOptions,
21 typeof BlankStackNavigator,
22 StackNavigationState<ParamListBase>,
23 BlankStackNavigationEventMap
24>(BlankStackNavigator);

The bundled component stack and bundled native-stack creator have been removed. Replace component stack with Blank Stack. Replace the bundled native stack with @react-navigation/native-stack plus withScreenTransitions.

Remove Version 3 navigator props

The current Blank Stack is a Standard Navigator and no longer exposes the Version 3 nativeScreens or enableNativeScreens presentation switches. Remove those props. Blank Stack now participates directly in the React Navigation tree that renders it.

Breaking: independent was removed

Blank Stack no longer accepts the independent navigator prop or exports BlankStackFactoryOptions. By the final Version 3 releases, independent no longer created the isolated container its name promised. Version 4 removes the prop instead of preserving configuration with no effect.

For normal nested navigation, remove independent without replacing it. If the flow intentionally needs a separate navigation tree, wrap its own NavigationContainer in React Navigation's NavigationIndependentTree. React Navigation documents this as an advanced setup: the nested tree is disconnected from its parent, and navigation cannot cross between them. See Independent navigation containers.

Remove deprecated transition aliases

Version 4 removes compatibility fields that Version 3 kept temporarily. Common replacements include:

  • snapVelocityImpactgestureSnapVelocityImpact
  • expandViaScrollViewsheetScrollGestureBehavior
  • gestureResponseDistance and gestureActivationArea → the area field on each gestureDirection entry
  • gestureDrivesProgress and gestureProgressMode → read transitionProgress when interpolation progress must exclude live gesture movement
  • gesture activeinitiator
  • gesture directioninitiator for the gesture that activated the transition
  • normalizedX, normalizedY, isDragging, and isDismissingnormX, normY, dragging, and dismissing

useScreenAnimation now uses depth targets. Replace "self", "parent", "root", and { ancestor } with the matching { depth } target.

Version 4 distinguishes contentComponent from surfaceComponent. Use contentComponent for the outer screen-motion and navigation-geometry layer. Use surfaceComponent for the nested visual shell when filters, clipping, backgrounds, or corner treatments should not wrap shared-element fallback content.

Version 4 also removes ignored bounds and zoom compatibility options, including bounds().math(), raw, gestures, legacy zoom opacity ranges, and old drag sensitivity fields. Use bounds(id).values(), offset, and the current drag configuration instead.

Replace removed shared presets

Version 4 removes Transition.Presets.SharedIGImage(), Transition.Presets.SharedAppleMusic(), and Transition.Presets.SharedXImage(). These presets combined product-specific gesture, masking, backdrop, and bounds decisions into fixed recipes that were difficult to extend.

For an opinionated source-to-destination transition, use the supported zoom recipe:

TSX

1screenStyleInterpolator: ({ bounds }) => {
2 "worklet";
3
4 return bounds(id).navigation.zoom();
5};

When the transition needs its own gesture response, layer choreography, or visual treatment, build it in screenStyleInterpolator with bounds(id).styles() or bounds(id).values(). See Bounds Transitions for the lower-level geometry helpers and Zoom for the built-in recipe.

Check inactive screen behavior

The four inactiveBehavior values remain hide, pause, unmount, and keep. Their implementation changed from React Native Screens and React Freeze to React 19.2 Activity.

Test screens with subscriptions, text inputs, scroll state, nested navigation, and expensive effects. Activity pauses effects and deprioritizes hidden work, while Screen Transitions keeps paint visible when a transition still needs the inactive route.

Verify the app

Run these cases on iOS and Android:

  • rapid pushes and programmatic pops
  • gesture cancellation and repeated dismissals
  • deep bounds stacks
  • floating overlays during overlapping transitions
  • all four inactive behavior modes
  • nested stacks and deep links used by the app