v3.7 focuses on making the stack runtime easier to adopt in existing apps and more predictable during complex dismissals, nested gestures, and retained closing routes.
Features
withScreenTransitions Adapter
v3.7 adds withScreenTransitions() for teams that already use @react-navigation/native-stack.
The forked native-stack version from this package is deprecated so the package can focus on the transition layer while your app continues to benefit from the latest native-stack implementation.
Instead of importing the bundled native-stack navigator from this package, wrap React Navigation's native stack:
TSX
Transition behavior still opts in per screen or group:
TSX
Blank Stack Lifecycle
Blank stack now has explicit inactive-screen lifecycle control through inactiveBehavior.
TSX
The supported behaviors are:
hide: keep inactive screens mounted, freeze inactive rendering where supported, and hide presentation after safe paintpause: keep the last painted UI visible and freeze inactive rendering where supportedunmount: remove the React subtree after safe paint when the route has no nested navigation statekeep: keep inactive screens mounted, visible, non-interactive, and running
The default is hide on native and unmount on web.
On web, use unmount for now. hide can hide paint but cannot pause React work in the current view fallback, and pause behaves closest to keep until the package can use React Activity.
This release also introduces a managed-stack controller for blank stack route retention. Closing routes are kept around long enough to finish their transition, removed routes can reuse their previous descriptor while closing, and inactive / inert / closing scenes are resolved more deterministically.
That also fixes a visible lifecycle bug during stacked dismissals. A screen that is already visible again, such as an index route underneath closing detail routes, should stay active and visible while the closing routes finish their exit animations.
The lifecycle work is covered by a new inactive-behavior test suite for hide, pause, unmount, and keep timing.
Reveal Background Scaling
bounds({ id }).navigation.reveal() now exposes the background scaling that was previously hardcoded.
TSX
backgroundScale controls the unfocused background content scale while reveal runs above it.
shouldBackgroundScaleResetOnSettled defaults to true. Reveal restores the background to scale 1 after settle so the next drag or programmatic dismiss can take a fresh measurement from the real screen geometry instead of from a scaled screen.
Experimental Transition Scopes
screenStyleInterpolator now receives an experimental transition() accessor for reading animation state from the current screen, ancestors, and descendants.
TSX
Calling transition() without a target returns the current transition scope. Negative depths resolve ancestors, positive depths resolve descendants, and depth: 0 resolves the current scope.
Returned scopes include the same interpolation props as the original call, including current, previous, next, active, inactive, progress, stackProgress, bounds, and another relative transition() function.
This is useful for nested transition choreography where a child interpolator needs to react to a parent gesture, or a parent interpolator needs to read a mounted child's transition state.
This API is experimental in v3.7. It is available for early nested choreography use, but the exact shape may change before it becomes stable.
Fixes
Gesture Ownership During Dismiss
Nested gestures are more predictable while screens are closing.
Previously, quickly dismissing screens in a nested stack could let the wrong gesture win. A parent layout could sometimes steal a drag from the visible child screen, or closing child screens could keep blocking the parent after the user was already back on a screen that should inherit the parent gesture.
v3.7 keeps gesture ownership aligned with the screen the user can actually interact with. Visible child screens keep their own gestures while they are on screen, and parent gestures become available again as soon as the visible child screen no longer owns that direction.
In practice, a child screen that still visibly owns the drag keeps the parent blocked. Once the visible child no longer owns that direction, the parent can respond without waiting for offscreen closing screens to finish.
This is most visible in overlay or nested-stack flows where several child routes are dismissed in sequence.
Activity During Retained Closes
Active and inert scene calculations now ignore routes that are retained only because they are closing.
Previously, a closing route could still affect which non-closing screen was marked active or inert. In stacked dismissals, that could make the index screen hide or unmount too early while another closing screen was still animating above it.
v3.7 computes the active/inert window from non-closing routes first, then marks closing routes separately. Closing routes stay mounted for their exit transition, but they no longer displace the visible non-closing route in activity calculations.
Measurement And Visibility
Blocked destination screens no longer use opacity: 0 before the first transition frame.
Instead, they are moved offscreen with a shared visibility-block offset, and destination measurements are normalized before viewport guards and bounds writes. This avoids opacity-based visibility blocking while still keeping pre-transition destination capture out of view.
The change was made to avoid platform sampling issues, especially on physical iOS devices with Liquid Glass-style effects.
Reveal Layering
Reveal no longer applies position: "relative" and a focused-screen zIndex to the focused source element.
That method is not working as intended today. There are too many cases where a reveal boundary needs to live inside a FlatList, list header, sectioned list, or another constrained layout, and zIndex is not a reliable way to lift that element above the rest of the transition.
Later versions will use an opt-in react-native-teleport path so reveal can avoid those layout constraints without breaking the source layout.
Migration Notes
Native Stack Adapter
This release deprecates the bundled native-stack creator from react-native-screen-transitions/native-stack.
The bundled createNativeStackNavigator() integration remains available for compatibility, but new native-stack usage should prefer @react-navigation/native-stack plus withScreenTransitions().
Native Screen Naming
Blank stack now prefers the navigator prop name nativeScreens.
TSX
enableNativeScreens still works as a deprecated alias. Use nativeScreens={false} when a blank stack should render as regular React Native views instead of react-native-screens primitives.
- Replace new imports from
react-native-screen-transitions/native-stackwith@react-navigation/native-stackpluswithScreenTransitions(). - Use
inactiveBehaviorwhen a blank-stack screen needs explicit hide / pause / unmount / keep behavior. - Prefer
nativeScreensover the deprecatedenableNativeScreensprop. - Tune reveal background motion with
backgroundScale. - Leave
shouldBackgroundScaleResetOnSettledat its default unless you deliberately want the background to remain scaled while idle. - Treat
transition()inscreenStyleInterpolatoras experimental. It is intended for nested choreography and may tighten before the next stable API pass.