Creates a native stack navigator that extends @react-navigation/native-stack with custom transition support. Use this when you need native screen primitives with custom animations.
Function Signature
function createNativeStackNavigator <
ParamList extends ParamListBase = ParamListBase ,
NavigatorID extends string | undefined = undefined
>( config ?: StaticConfig ) : TypedNavigator < TypeBag , Config >
Type Parameters
ParamList
ParamListBase
default: "ParamListBase"
The parameter list for the navigator, defining route names and their parameters
NavigatorID
string | undefined
default: "undefined"
Optional unique identifier for the navigator instance
Parameters
Optional static configuration for the navigator (rarely needed)
Return Value
TypedNavigator
TypedNavigator<TypeBag, Config>
Returns a typed navigator object containing:
Navigator: The navigator component
Screen: The screen component for defining routes
Group: Component for grouping screens with shared options
Import
import { createNativeStackNavigator } from "react-native-screen-transitions/native-stack" ;
Usage
Basic Setup
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 } />
< Stack.Screen
name = "Detail"
component = { DetailScreen }
options = { {
enableTransitions: true ,
... Transition . Presets . SlideFromBottom (),
} }
/>
</ Stack.Navigator >
);
}
Important : You must set enableTransitions: true on screens where you want custom transitions. Without this flag, the screen will use native platform defaults.
With TypeScript
import { createNativeStackNavigator } from "react-native-screen-transitions/native-stack" ;
import type { NativeStackNavigationProp } from "react-native-screen-transitions/native-stack" ;
type RootStackParamList = {
Home : undefined ;
Detail : { id : string };
Profile : { userId : string };
};
const Stack = createNativeStackNavigator < RootStackParamList >();
// Type-safe navigation prop
type HomeScreenProps = {
navigation : NativeStackNavigationProp < RootStackParamList , 'Home' >;
};
function HomeScreen ({ navigation } : HomeScreenProps ) {
return (
< Button
title = "Go to Detail"
onPress = { () => navigation . navigate ( 'Detail' , { id: '123' }) }
/>
);
}
The Native Stack supports all standard @react-navigation/native-stack header options:
< Stack.Screen
name = "Detail"
component = { DetailScreen }
options = { {
enableTransitions: true ,
title: "Detail Screen" ,
headerShown: true ,
headerStyle: { backgroundColor: '#f4511e' },
headerTintColor: '#fff' ,
headerTitleStyle: { fontWeight: 'bold' },
... Transition . Presets . SlideFromBottom (),
} }
/>
Features
Custom Animations
When enableTransitions: true is set, you get full animation control:
< Stack.Screen
name = "Detail"
options = { {
enableTransitions: true ,
screenStyleInterpolator : ({ progress , layouts : { screen } }) => {
"worklet" ;
return {
contentStyle: {
opacity: interpolate ( progress , [ 0 , 1 , 2 ], [ 0 , 1 , 0 ]),
transform: [{
translateY: interpolate (
progress ,
[ 0 , 1 ],
[ screen . height , 0 ]
),
}],
},
};
},
} }
/>
Without enableTransitions, screens use native platform transitions:
< Stack.Screen
name = "Settings"
component = { SettingsScreen }
// No enableTransitions = native platform behavior
options = { {
title: "Settings" ,
} }
/>
Mixed Approach
You can mix custom and native transitions in the same stack:
< Stack.Navigator >
{ /* Native transition */ }
< Stack.Screen name = "Home" component = { HomeScreen } />
{ /* Custom transition */ }
< Stack.Screen
name = "Modal"
component = { ModalScreen }
options = { {
enableTransitions: true ,
... Transition . Presets . SlideFromBottom (),
} }
/>
{ /* Native transition */ }
< Stack.Screen name = "Settings" component = { SettingsScreen } />
</ Stack.Navigator >
When to Use
Use Native Stack When
You need native screen headers
Mixing custom and platform transitions
Gradual migration from native-stack
Platform-specific features required
Use Blank Stack Instead
You want custom animations everywhere
You need maximum control
Building from scratch
No need for native headers
Caveats
The Native Stack uses transparent modal presentation to intercept transitions. This 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.
Architecture
Base : Extends @react-navigation/native-stack
Intercept Method : Uses transparent modal presentation to intercept transitions
Animation Engine : Reanimated worklets on UI thread (when enableTransitions: true)
Headers : Native platform headers fully supported
Comparison with Blank Stack
Feature Native Stack Blank Stack Custom animations ✓ (with flag) ✓ (always) Platform defaults ✓ ✗ Native headers ✓ ✗ Touch responsiveness Good Excellent Setup complexity Medium Simple Performance Excellent Excellent
Exported Types
import type {
NativeStackNavigationOptions ,
NativeStackNavigationProp ,
NativeStackScreenProps ,
NativeStackNavigatorProps ,
NativeStackNavigationEventMap ,
NativeStackOverlayProps ,
NativeStackOptionsArgs ,
NativeStackHeaderProps ,
NativeStackHeaderLeftProps ,
NativeStackHeaderRightProps ,
} from "react-native-screen-transitions/native-stack" ;
Migration from @react-navigation/native-stack
// Before
import { createNativeStackNavigator } from '@react-navigation/native-stack' ;
// After
import { createNativeStackNavigator } from 'react-native-screen-transitions/native-stack' ;
// Then add custom transitions where needed
< Stack.Screen
name = "Detail"
options = { {
enableTransitions: true , // Add this
... Transition . Presets . SlideFromBottom (), // Add this
} }
/>