Generated banner for React Navigation
Generated logo for React Navigation

React Navigation

CallstackOfficialPublished by Callstack

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

Provides React Navigation UI patterns for stacks, tabs, drawers etc. Use when building navigation UIs with React Navigation, configuring headers, bottom sheets or handling safe areas and insets.
— the description by Callstack

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured reference for building navigation interfaces in React applications using React Navigation 7. It covers both the modern Static API and the traditional Dynamic API, offering guidance on implementing stacks, tabs, drawers, and sheets. The documentation includes best practices for configuring headers, handling safe areas, and managing navigation state across different platforms.

What it does

  • Provides patterns for implementing stack, tab, and drawer navigation.
  • Explains how to configure headers and navigation UI elements.
  • Offers guidance on handling safe areas and screen insets.
  • Demonstrates how to integrate icons and custom backgrounds into navigation components.
  • Supports both Static and Dynamic API styles for navigation configuration.
  • Includes techniques for programmatic navigation control and scroll-to-top functionality.

When to use it

  • When building navigation structures for React-based mobile or web applications.
  • When you need to implement consistent UI patterns like sidebars, bottom tabs, or modals.
  • When configuring platform-specific navigation behaviors or safe-area insets.
  • When migrating or setting up navigation in a React Navigation 7 environment.

Advantages

  • Provides clear API selection guidance for new and existing projects.
  • Offers standardized patterns for common navigation UI components.
  • Includes practical code examples for both Static and Dynamic APIs.
  • Addresses cross-platform layout requirements for web and mobile.

Usage examples

“How do I create a bottom tab navigator in React Navigation 7?”
The skill provides code snippets for both Static and Dynamic APIs, showing how to use createBottomTabNavigator and configure tab icons.
“How can I handle safe areas in my navigation header?”
The skill directs you to the safe-areas reference, explaining how to manage status bar and header insets for a consistent UI.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/callstackincubator/react-navigation/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip react-navigation.zip -d .agents/skills

Documentation by Callstack

React Navigation

Overview

Guide for building navigation UIs with React Navigation.

This skill only applies to React Navigation 7. The API and patterns may not work with different versions.

API Selection

React Navigation offers two API - object-based Static API and component-based Dynamic API.

  • Existing Apps: Check the current navigation setup and follow the same API style when using the references

  • New Apps: If the app does not have an existing navigation setup yet, prefer Static API

When to Apply

Reference this skill when:

  • Building navigation UI patterns such as stacks, tabs, drawers, sheets etc.

  • Configuring headers and other built-in navigator UI

  • Handling safe areas and insets in navigation UI

References

FileDescription
stacks.mdStack based navigation
form-sheet.mdBottom sheet and form sheets
bottom-tabs.mdCross-platform bottom tabs
native-bottom-tabs.mdNative bottom tabs
material-top-tabs.mdSwipeable Top tabs
drawers.mdDrawer navigation and sidebars
header.mdConfiguring headers
safe-areas.mdSafe-area handling

Problem -> Skill Mapping

ProblemStart With
Showing screens and modals in a stackstacks.md
Showing bottom sheets or form sheetsform-sheet.md
Showing screens in bottom tabs or responsive sidebars with web supportbottom-tabs.md
Showing screens in native tabs on iOS & Androidnative-bottom-tabs.md
Showing content in swipeable top tabsmaterial-top-tabs.md
Using a drawer or sidebardrawers.md
Configuring the header in bottom tab or drawer navigatorheader.md
Handling safe-area such as status bar, header insets, tab bar insets etc.safe-areas.md

Files

references/bottom-tabs.md


title: Bottom Tabs impact: HIGH tags: react-navigation, bottom-tabs, tab-bar, icons, blur, sidebar, header

Skill: Bottom Tabs

Description

Use createBottomTabNavigator for cross-platform tab navigation with a tab bar that can stay at the bottom on smaller screens and move to the side on larger layouts if the app needs web support.

Conditionally use native-bottom-tabs.md on Android and iOS for a native tab bar.

When to Use

  • Building primary app destinations behind a tab bar

  • The app needs to run on web and mobile

Basic Example

Static API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const AppTabs = createBottomTabNavigator({
  screens: {
    Home: HomeScreen,
    Profile: ProfileScreen,
  },
});

Dynamic API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

Common Features

Displaying Icons

Use tabBarIcon in screenOptions or per-screen options. Optionally use tabBarActiveTintColor and tabBarInactiveTintColor to change the color passed to the icon.

Static API

import Ionicons from '@expo/vector-icons/Ionicons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const AppTabs = createBottomTabNavigator({
  screenOptions: ({ route }) => ({
    tabBarIcon: ({ focused, color, size }) => {
      let iconName;

      switch (route.name) {
        case 'Home':
          iconName = focused ? 'home' : 'home-outline';
          break;
        default:
          iconName = focused ? 'settings' : 'settings-outline';
          break;
      }

      return <Ionicons name={iconName} size={size} color={color} />;
    },
    tabBarActiveTintColor: 'tomato',
    tabBarInactiveTintColor: 'gray',
  }),
  screens: {
    Home: HomeScreen,
    Settings: SettingsScreen,
  },
});

Dynamic API

import Ionicons from '@expo/vector-icons/Ionicons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName;

          switch (route.name) {
            case 'Home':
              iconName = focused ? 'home' : 'home-outline';
              break;
            default:
              iconName = focused ? 'settings' : 'settings-outline';
              break;
          }

          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: 'tomato',
        tabBarInactiveTintColor: 'gray',
      })}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

The tabBarIcon option can render any React element. Choose between the icon libraries that best fit the app's design and environment:

  • @expo/vector-icons if Expo SDK is configured in the app

  • react-native-vector-icons for an app using React Native Community CLI

  • <Image> for local images

Scroll to Top on Tab Press

Use useScrollToTop on a scrollable ref inside a screen in the tab navigator to automatically scroll to the top when the tab is pressed while already focused.

import * as React from 'react';
import { ScrollView } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';

function FeedScreen() {
  const ref = React.useRef(null);

  useScrollToTop(ref);

  return <ScrollView ref={ref}>{/* content */}</ScrollView>;
}
Custom Background Such as Blur

Use tabBarBackground for custom chrome such as blur effects, image, or gradient backgrounds. When the background should show through the tab bar, set tabBarStyle: { position: 'absolute' } and use useBottomTabBarHeight inside the screens to pad the content.

Static API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { BlurView } from 'expo-blur';
import { StyleSheet } from 'react-native';

const AppTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarStyle: { position: 'absolute' },
    tabBarBackground: () => (
      <BlurView tint="light" intensity={100} style={StyleSheet.absoluteFill} />
    ),
  },
  screens: {
    Home: HomeScreen,
    Profile: ProfileScreen,
  },
});

Dynamic API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { BlurView } from 'expo-blur';
import { StyleSheet } from 'react-native';

const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator
      screenOptions={{
        tabBarStyle: { position: 'absolute' },
        tabBarBackground: () => (
          <BlurView
            tint="light"
            intensity={100}
            style={StyleSheet.absoluteFill}
          />
        ),
      }}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}
Custom Tab Bar

Use the tabBar option if a custom design is needed. Use the state prop to access the list of screens and descriptors to access the options for each screen. Use the navigation prop passed to the tab bar for navigation instead of useNavigation.

import { Text, View } from 'react-native';
import { useLinkBuilder } from '@react-navigation/native';
import { PlatformPressable } from '@react-navigation/elements';

function MyTabBar({ state, descriptors, navigation }) {
  const { buildHref } = useLinkBuilder();

  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label =
          options.tabBarLabel !== undefined
            ? options.tabBarLabel
            : options.title !== undefined
              ? options.title
              : route.name;

        const isFocused = state.index === index;

        return (
          <PlatformPressable
            key={route.key}
            href={buildHref(route.name, route.params)}
            onPress={() => {
              const event = navigation.emit({
                type: 'tabPress',
                target: route.key,
                canPreventDefault: true,
              });

              if (!isFocused && !event.defaultPrevented) {
                navigation.navigate(route.name, route.params);
              }
            }}
            onLongPress={() =>
              navigation.emit({
                type: 'tabLongPress',
                target: route.key,
              })
            }
            style={{ flex: 1, alignItems: 'center', paddingVertical: 12 }}
          >
            <Text style={{ opacity: isFocused ? 1 : 0.6 }}>{label}</Text>
          </PlatformPressable>
        );
      })}
    </View>
  );
}

Static API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const AppTabs = createBottomTabNavigator({
  tabBar: (props) => <MyTabBar {...props} />,
  screens: {
    Home: HomeScreen,
    Profile: ProfileScreen,
  },
});

Dynamic API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator tabBar={(props) => <MyTabBar {...props} />}>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}
Sidebar

Set tabBarPosition to left or right to render the tab bar as a sidebar. Choose the position based on the screen width for responsive layouts.

Static API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const AppTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarPosition: 'left',
  },
  screens: {
    Home: HomeScreen,
    Profile: ProfileScreen,
  },
}).with(({ Navigator }) => {
  const dimensions = useWindowDimensions();

  return (
    <Navigator
      screenOptions={{
        tabBarPosition: dimensions.width >= 768 ? 'left' : 'bottom',
      }}
    />
  );
});

Dynamic API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { useWindowDimensions } from 'react-native';

const Tab = createBottomTabNavigator();

function AppTabs() {
  const dimensions = useWindowDimensions();

  return (
    <Tab.Navigator
      screenOptions={{
        tabBarPosition: dimensions.width >= 768 ? 'left' : 'bottom',
      }}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

For a compact sidebar, use tabBarVariant: 'material' together with tabBarLabelPosition: 'below-icon'.

Customizing Header

Bottom tabs show a header by default. Use header.md for common customization patterns.

A custom header can be shown with the header option if a custom design is needed.

Static API

import { getHeaderTitle } from '@react-navigation/elements';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const AppTabs = createBottomTabNavigator({
  screens: {
    Home: {
      screen: HomeScreen,
      options: {
        headerStyle: {
          height: 80,
        },
        header: ({ route, options }) => {
          const title = getHeaderTitle(options, route.name);

          return <MyHeader title={title} style={options.headerStyle} />;
        },
      },
    },
  },
});

Dynamic API

import { getHeaderTitle } from '@react-navigation/elements';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{
          headerStyle: {
            height: 80,
          },
          header: ({ route, options }) => {
            const title = getHeaderTitle(options, route.name);

            return <MyHeader title={title} style={options.headerStyle} />;
          },
        }}
      />
    </Tab.Navigator>
  );
}
  • Set headerShown: false to hide the header.

  • If a custom header uses a non-default height, set headerStyle: { height: ... } explicitly to avoid measurement glitches.

Hiding Tab Bar on Certain Screens

The tab bar is shown on all screens in the tab navigator. To hide the tab bar on certain screens, put those screens in a parent stack navigator instead.

Static API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const HomeTabs = createBottomTabNavigator({
  screens: {
    Home: HomeScreen,
    Feed: FeedScreen,
    Notifications: NotificationsScreen,
  },
});

const AppStack = createNativeStackNavigator({
  screens: {
    Main: {
      screen: HomeTabs,
      options: {
        headerShown: false,
      },
    },
    Profile: ProfileScreen,
    Settings: SettingsScreen,
  },
});

Dynamic API

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

function HomeTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Feed" component={FeedScreen} />
      <Tab.Screen name="Notifications" component={NotificationsScreen} />
    </Tab.Navigator>
  );
}

function AppStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Main"
        component={HomeTabs}
        options={{
          headerShown: false,
        }}
      />
      <Stack.Screen name="Profile" component={ProfileScreen} />
      <Stack.Screen name="Settings" component={SettingsScreen} />
    </Stack.Navigator>
  );
}
  • Prefer this structure over trying to hide the parent tab bar from screens inside the tab navigator as it can lead to layout glitches.

  • Use stacks.md for stack-specific options on the full-screen routes.

Canonical Docs

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Callstack
Publisher
Callstack (Official)
Source
callstackincubator/agent-skills · skills/react-navigation · commit 59e9d17
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Callstack or Callstack.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download react-navigation.zip