Stack Navigator: What It Is, Stack Navigation in React Native

Author: IT Sectr Published: 2026-02-22 Reading time: 11 min

Stack Navigator — a React Navigation library component for managing mobile app screens using the stack principle (LIFO). Each new screen is placed on top of the previous one, and the «Back» button removes the top screen and returns the user to the previous one. Read more about navigation architecture in the official React Navigation documentation.

Key Takeaways

  • Stack Navigator — a React Navigation component for managing screens using the stack principle (LIFO)
  • Stack navigation — each screen is placed on top of the previous one; the «Back» button removes the current screen
  • Native Stack — native implementation via UINavigationController (iOS) and Fragment (Android)
  • Animations — built-in transitions (slide, fade, none) and custom animations via cardStyleInterpolator
  • TypeScript — full typing of navigation parameters via RootStackParamList

What is Stack Navigator?

Stack Navigator is one of the basic navigators of the React Navigation library that implements the stack screen model. It provides the navigation mobile users are familiar with: opening a new screen is accompanied by a slide-right animation, and the «Back» button or swipe gesture returns to the previous screen. Stack Navigator supports iOS and Android, using native platform components for maximum performance.

React Navigation is the most popular navigation library for React Native, installed in 85% of projects (according to npm data, 2026). Stack Navigator is part of its core and is available in two implementations: createNativeStackNavigator (native, recommended) and createStackNavigator (JavaScript, for complex custom animations). The native version appeared in React Navigation v5 and became the standard in v6+.

The main advantage of Stack Navigator is the natural behavior familiar to iOS and Android users. On iOS, the stack is visually represented by UINavigationController, on Android — by FragmentManager with slide animation. The developer does not need to implement stack logic manually — the navigator manages screen states, back stack, and animations automatically.

How Stack Navigation Works

Stack navigation is based on the LIFO (Last In, First Out) principle. When a user opens a new screen, the navigator places it on top of the stack. When «Back» is pressed, the top screen is removed and the user sees the previous one. The stack can contain any number of screens — the only limitation is device memory.

Each screen in the stack preserves its state. When returning to a previous screen, its state is restored automatically. This distinguishes a stack from other navigation types (Tab, Drawer), where screens may be recreated. React Navigation manages state through its own navigation context mechanism.

ActionResultExample
navigatePlaces a screen on top of the stacknavigation.navigate('Profile')
goBackRemoves the top screen from the stacknavigation.goBack()
pushForcefully adds a new screennavigation.push('Profile')
popToTopReturns to the root screennavigation.popToTop()
resetReplaces the entire stack with a new setnavigation.reset({ index: 0, routes: [...] })

Swipe Gesture for Going Back

On iOS, Stack Navigator supports a swipe-from-left-edge gesture to go back — this is standard iOS behavior that users expect. On Android, the gesture is disabled by default, but can be enabled via the gestureEnabled option. In Native Stack, the gesture works natively without JavaScript-thread delays.

Native Stack vs JS Stack

React Navigation offers two types of Stack Navigator: Native Stack (createNativeStackNavigator) and JS Stack (createStackNavigator). The main difference is where the animation executes. Native Stack uses native animation drivers from iOS and Android, whereas JS Stack runs through the React Native JavaScript thread. The choice between them depends on performance and customization requirements.

Native Stack is recommended for most projects. It provides smooth 60 FPS animations without blocking the JS thread, supports the system swipe-back gesture on iOS, and uses native transitions — slide on iOS, fade on Android. However, Native Stack is limited in animation customization: only a predefined set of transitions is available.

JS Stack gives full control over animations via cardStyleInterpolator. The developer can create any animation: scaling, rotation, parallax, custom curves. The downside is that animations run in the JS thread, which can cause frame drops on weak devices with complex transitions. For 70% of projects, Native Stack is more than sufficient.

typescript
// Native Stack — recommended implementation
import { createNativeStackNavigator } from '@react-navigation/native-stack';

type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string; name: string };
  Settings: undefined;
};

const Stack = createNativeStackNavigator<RootStackParamList>();

function AppNavigator() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: true }}>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Profile" component={ProfileScreen} />
      <Stack.Screen name="Settings" component={SettingsScreen} />
    </Stack.Navigator>
  );
}

Installing and Setting Up Stack Navigator

To get started with Stack Navigator, you need to install React Navigation and its dependencies. The minimal set includes @react-navigation/native, @react-navigation/native-stack, and react-native-screens. After installation, the app is wrapped in NavigationContainer — a context that provides navigation state to all child components.

bash
# Installing React Navigation dependencies
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context

# For iOS — install pod
cd ios && pod install && cd ..

After installation, Stack.Navigator is created with specific screens defined in RootStackParamList. Each screen is linked to a React component via the component prop. The navigator can be root-level or nested inside another navigator (Tab, Drawer). For configuration, screenOptions are used — either common for all screens or individual for each.

typescript
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

type RootStackParamList = {
  Home: undefined;
  Details: { itemId: number; title: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home"
        screenOptions={{
          headerStyle: { backgroundColor: '#6200ee' },
          headerTintColor: '#fff',
          gestureEnabled: true,
        }}>
        <Stack.Screen name="Home" component={HomeScreen}
          options={{ title: 'Home' }} />
        <Stack.Screen name="Details" component={DetailsScreen}
          options={({ route }) => ({ title: route.params.title })} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Stack Navigator Parameters and Customization

Stack Navigator provides many options for customizing appearance and behavior. The main parameters are set via screenOptions at the Navigator level or options at the Screen level. The developer can configure the header, transition animation, swipe gesture, card style, and background dimming. The flexibility of settings allows adapting navigation to the app's design system.

OptionTypeDescription
headerShownbooleanShow or hide the screen header
headerStyleobjectHeader bar style (backgroundColor, elevation)
headerBackTitlestring«Back» button text (iOS)
gestureEnabledbooleanEnable swipe-back gesture
animationstringAnimation type: slide_from_right, fade, none
contentStyleobjectInner screen area style

Custom Animations via cardStyleInterpolator

For JS Stack, cardStyleInterpolator allows creating arbitrary transition animations between screens. This is a powerful tool for implementing unique visual effects: scaling, rotation, parallax, horizontal flip. The function receives current animation progress values (current, next) and returns styles for the elements being animated.

Navigation Typing with TypeScript

Stack Navigator supports full typing via TypeScript. To do this, RootStackParamList is defined — an object type where keys are screen names and values are parameter types. After typing, navigation.navigate and route.params get autocompletion and type checking. This eliminates parameter-passing errors at compile time.

typescript
type RootStackParamList = {
  Home: undefined;
  Product: { id: string; category: string };
  Checkout: { items: CartItem[]; total: number };
};

// Typed screen
type ProductScreenProps = NativeStackScreenProps<RootStackParamList, 'Product'>;

function ProductScreen({ navigation, route }: ProductScreenProps) {
  const { id, category } = route.params;

  return (
    <View>
      <Text>Product {id} — {category}</Text>
      <Button title="Add to cart"
        onPress={() => navigation.navigate('Checkout', {
          items: [{ id, quantity: 1 }],
          total: 99.99,
        })} />
    </View>
  );
}

Advanced Scenarios: Modal Windows and Groups

Stack Navigator supports screen grouping and modal windows. Groups (Screen Group) allow applying common settings to multiple screens without duplication. Modal windows are implemented via stack presentation: 'modal' — the screen opens from the bottom with background dimming, like a system modal on iOS. This option is only available in Native Stack.

For complex navigation, Stack Navigator can be nested inside a Tab Navigator or Drawer Navigator. For example, the «Home» tab has its own stack of screens, and the «Profile» tab has its own. This composition of navigators is the standard approach for production applications. Each stack is isolated: the back stack within a tab does not affect other tabs.

typescript
// Nested stack in Tab Navigator
const HomeStack = createNativeStackNavigator<HomeStackParamList>();

function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Feed" component={FeedScreen} />
      <HomeStack.Screen name="PostDetail" component={PostDetailScreen}
        options={{ presentation: 'modal' }} />
    </HomeStack.Navigator>
  );
}

// Screen groups with shared options
<Stack.Navigator>
  <Stack.Group screenOptions={{ headerShown: true }}>
    <Stack.Screen name="Main" component={MainScreen} />
    <Stack.Screen name="About" component={AboutScreen} />
  </Stack.Group>
  <Stack.Screen name="Auth" component={AuthScreen}
    options={{ presentation: 'modal', headerShown: false }} />
</Stack.Navigator>

Frequently Asked Questions

What is the difference between navigate and push in Stack Navigator?

navigate first looks for an existing screen with that name in the stack and navigates to it if found. push always adds a new screen to the top of the stack, even if one already exists. push is useful when you need to open the same screen with different data (e.g., a user profile).

How to pass parameters to a screen in Stack Navigator?

Parameters are passed as the second argument of the navigate method: navigation.navigate('Profile', { userId: '123', name: 'John' }). On the receiving screen, parameters are available via route.params. Parameter types are defined in RootStackParamList for TypeScript autocompletion.

Stack Navigator or Tab Navigator — which one to choose?

Stack Navigator is suitable for linear navigation (screen → details → editing). Tab Navigator is for parallel sections of the app (Home, Search, Profile). In production projects, they are combined: Tab Navigator contains several Stack Navigators for each tab.

How does the «Back» button work in Stack Navigator?

By default, Stack Navigator adds a «Back» button in the header for all screens except the root one. On iOS, the swipe-from-left-edge gesture also works. The navigation.goBack() method removes the current screen from the stack and returns the user to the previous one.

Can the animation in Stack Navigator be fully customized?

Native Stack provides predefined animations: slide_from_right, fade, none. For full customization, JS Stack is used with cardStyleInterpolator — a function that returns card styles on each animation frame. This allows creating any transitions: scaling, parallax, 3D rotation.

Summary

  • Stack Navigator — a React Navigation component for managing screens using the LIFO principle with native performance
  • Native Stack (createNativeStackNavigator) uses native iOS and Android animations and is recommended for 85% of projects
  • RootStackParamList provides full typing of navigation parameters in TypeScript
  • Screen options allow configuring the header, animations, gestures, and style of each screen
  • Groups and modals — built-in mechanisms for organizing related screens and modal windows
  • Navigator composition — Stack Navigator is nested in Tab/Drawer for production architecture
  • JS Stack gives full control over animations via cardStyleInterpolator for unique transitions

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also