Native Bottom Tabs Navigator
This navigator is currently experimental. The API will change in future releases.
Currently only iOS and Android are supported. Use createBottomTabNavigator for web support.
Native Bottom Tabs displays screens with a tab bar to switch between them.
The navigator uses native components on iOS and Android for better platform integration. On iOS, it uses UITabBarController and on Android, it uses BottomNavigationView.
Installation
To use this navigator, ensure that you have @react-navigation/native and its dependencies (follow this guide), then install @react-navigation/bottom-tabs:
- npm
- Yarn
- pnpm
npm install @react-navigation/bottom-tabs
yarn add @react-navigation/bottom-tabs
pnpm add @react-navigation/bottom-tabs
Usage
To use this navigator, import it from @react-navigation/bottom-tabs/unstable:
- Static
- Dynamic
import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
const MyTabs = createNativeBottomTabNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});
import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
const Tab = createNativeBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
API Definition
Props
In addition to the common props shared by all navigators, the bottom tab navigator accepts the following additional props:
backBehavior
This controls what happens when goBack is called in the navigator. This includes pressing the device's back button or back gesture on Android.
It supports the following values:
firstRoute- return to the first screen defined in the navigator (default)initialRoute- return to initial screen passed ininitialRouteNameprop, if not passed, defaults to the first screenorder- return to screen defined before the focused screenhistory- return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the historyfullHistory- return to last visited screen in the navigator; doesn't drop duplicate entries unlikehistory- this behavior is useful to match how web pages worknone- do not handle back button
Options
The following options can be used to configure the screens in the navigator. These can be specified under screenOptions prop of Tab.Navigator or options prop of Tab.Screen.
title
Generic title that can be used as a fallback for headerTitle and tabBarLabel.
tabBarSystemItem
Uses iOS built-in tab bar items with standard iOS styling and localized titles. Supported values:
bookmarkscontactsdownloadsfavoritesfeaturedhistorymoremostRecentmostViewedrecentssearchtopRated
If set to search, it's positioned next to the tab bar on iOS 26 and above.
The tabBarIcon and tabBarLabel options will override the icon and label from the system item. If you want to keep the system behavior on iOS, but need to provide icon and label for other platforms, use Platform.OS or Platform.select to conditionally set undefined for tabBarIcon and tabBarLabel on iOS.
tabBarLabel
Title string of a tab displayed in the tab bar.
Overrides the label provided by tabBarSystemItem on iOS.
If not provided, or set to undefined:
- The system values are used if
tabBarSystemItemis set on iOS. - Otherwise, it falls back to the
titleor route name.
tabBarLabelVisibilityMode
The label visibility mode for the tab bar items. Supported values:
auto- the system decides when to show or hide labelsselected- labels are shown only for the selected tablabeled- labels are always shownunlabeled- labels are never shown
Only supported on Android.
tabBarLabelStyle
Style object for the tab label. Supported properties:
fontFamilyfontSizefontWeightfontStyle
Example:
tabBarLabelStyle: {
fontSize: 16,
fontFamily: 'Georgia',
fontWeight: 300,
},
tabBarIcon
Icon to display for the tab. It overrides the icon provided by tabBarSystemItem on iOS.
It can be an icon object or a function that given { focused: boolean, color: string, size: number } returns an icon object.
The icon can be of following types:
-
Local image - Supported on iOS and Android
tabBarIcon: {
type: 'image',
source: require('./path/to/icon.png'),
}On iOS, you can additionally pass a
tintedproperty to control whether the icon should be tinted with the active/inactive color:tabBarIcon: {
type: 'image',
source: require('./path/to/icon.png'),
tinted: false,
}The image is tinted by default.
-
SF Symbols name - Supported on iOS
tabBarIcon: {
type: 'sfSymbol',
name: 'heart',
} -
Drawable resource name - Supported on Android
tabBarIcon: {
type: 'drawableResource',
name: 'sunny',
}
To render different icons for active and inactive states, you can use a function:
tabBarIcon: ({ focused }) => {
return {
type: 'sfSymbol',
name: focused ? 'heart' : 'heart-outline',
};
},
This is only supported on iOS. On Android, the icon specified for inactive state will be used for both active and inactive states.
To provide different icons for different platforms, you can use Platform.select:
tabBarIcon: Platform.select({
ios: {
type: 'sfSymbol',
name: 'heart',
},
android: {
type: 'drawableResource',
name: 'heart_icon',
},
});
tabBarBadge
Text to show in a badge on the tab icon. Accepts a string or a number.
tabBarBadgeStyle
Style for the badge on the tab icon. Supported properties:
backgroundColorcolor
Example:
tabBarBadgeStyle: {
backgroundColor: 'yellow',
color: 'black',
},
tabBarActiveTintColor
Color for the icon and label in the active tab.
tabBarInactiveTintColor
Color for the icon and label in the inactive tabs.
Only supported on Android.
tabBarActiveIndicatorColor
Background color of the active indicator.
Only supported on Android.
tabBarActiveIndicatorEnabled
Whether the active indicator should be used. Defaults to true.
Only supported on Android.
tabBarRippleColor
Color of the ripple effect when pressing a tab.
Only supported on Android.
tabBarStyle
Style object for the tab bar. Supported properties:
backgroundColor- Only supported on Android and iOS 18 and below.shadowColor- Only supported on iOS 18 and below.
tabBarBlurEffect
Blur effect applied to the tab bar on iOS 18 and lower when tab screen is selected.
Supported values:
none- no blur effectsystemDefault- default blur effect applied by the systemextraLightlightdarkregularprominentsystemUltraThinMaterialsystemThinMaterialsystemMaterialsystemThickMaterialsystemChromeMaterialsystemUltraThinMaterialLightsystemThinMaterialLightsystemMaterialLightsystemThickMaterialLightsystemChromeMaterialLightsystemUltraThinMaterialDarksystemThinMaterialDarksystemMaterialDarksystemThickMaterialDarksystemChromeMaterialDark
Defaults to systemDefault.
Only supported on iOS 18 and below.
tabBarControllerMode
The display mode for the tab bar. Supported values:
auto- the system sets the display mode based on the tab’s contenttabBar- the system displays the content only as a tab bartabSidebar- the tab bar is displayed as a sidebar
Only supported on iOS 18 and above. Not supported on tvOS.
tabBarMinimizeBehavior
The minimize behavior for the tab bar. Supported values:
auto- resolves to the system default minimize behaviornever- the tab bar does not minimizeonScrollDown- the tab bar minimizes when scrolling down and expands when scrolling back uponScrollUp- the tab bar minimizes when scrolling up and expands when scrolling back down
Only supported on iOS 26 and above.
lazy
Whether this screen should render only after the first time it's accessed. Defaults to true. Set it to false if you want to render the screen on the initial render of the navigator.
popToTopOnBlur
Boolean indicating whether any nested stack should be popped to the top of the stack when navigating away from this tab. Defaults to false.
It only works when there is a stack navigator (e.g. stack navigator or native stack navigator) nested under the tab navigator.
Header related options
The navigator renders a native stack header. It supports most of the header related options supported in @react-navigation/native-stack apart from the options related to the back button (prefixed with headerBack).
Events
The navigator can emit events on certain actions. Supported events are:
tabPress
This event is fired when the user presses the tab button for the current screen in the tab bar. By default a tab press does several things:
- If the tab is not focused, tab press will focus that tab
- If the tab is already focused:
- If the screen for the tab renders a scroll view, you can use
useScrollToTopto scroll it to top - If the screen for the tab renders a stack navigator, a
popToTopaction is performed on the stack
- If the screen for the tab renders a scroll view, you can use
To prevent the default behavior, you can call event.preventDefault:
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Do something manually
// ...
});
return unsubscribe;
}, [navigation]);
transitionStart
This event is fired when the transition animation starts for the current screen.
Example:
React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionStart', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
transitionEnd
This event is fired when the transition animation ends for the current screen.
Example:
React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionEnd', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
Helpers
The tab navigator adds the following methods to the navigation object:
jumpTo
Navigates to an existing screen in the tab navigator. The method accepts following arguments:
name- string - Name of the route to jump to.params- object - Screen params to use for the destination route.
navigation.jumpTo('Profile', { owner: 'Michaś' });