Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/felipe-software/react-native-jelly-tabs/llms.txt

Use this file to discover all available pages before exploring further.

Follow these steps to add a fully animated jelly tab bar to your Expo Router app. The entire integration takes less than five minutes.
1

Install the package and peer dependencies

If you have not installed react-native-jelly-tabs yet, follow the Installation guide to add the package and its peer dependencies, then rebuild your native app.
npm install react-native-jelly-tabs
npx expo install @react-native-masked-view/masked-view react-native-gesture-handler react-native-reanimated react-native-svg
npx expo prebuild
2

Wrap your app with GestureHandlerRootView

Gesture Handler requires GestureHandlerRootView at the very top of your component tree. In an Expo Router project this belongs in your root _layout.tsx.
import { GestureHandlerRootView } from "react-native-gesture-handler";

export default function RootLayout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      {/* <Tabs> and other providers go here */}
    </GestureHandlerRootView>
  );
}
Without this wrapper, tab gestures (dragging, long-press) will not fire.
3

Add JellyTabBar to your Expo Router Tabs layout

Pass JellyTabBar as the tabBar render prop on <Tabs>. The component accepts the same props object that Expo Router / React Navigation normally passes to a custom tab bar, so no extra adapter code is needed.Below is a complete, minimal app/_layout.tsx with three tabs — Home, Search, and Profile — using Material Icons:
import "react-native-gesture-handler";

import { MaterialIcons } from "@react-native-vector-icons/material-icons";
import { Tabs } from "expo-router";
import { JellyTabBar } from "react-native-jelly-tabs";
import { StatusBar } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaProvider } from "react-native-safe-area-context";

export default function RootLayout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <SafeAreaProvider>
        <StatusBar barStyle="dark-content" backgroundColor="#f5f1e8" />
        <Tabs
          screenOptions={{ headerShown: false }}
          tabBar={(props) => <JellyTabBar {...props} floating />}
        >
          <Tabs.Screen
            name="index"
            options={{
              title: "Home",
              tabBarIcon: ({ color, size }) => (
                <MaterialIcons color={color} name="home" size={size} />
              ),
            }}
          />
          <Tabs.Screen
            name="search"
            options={{
              title: "Search",
              tabBarIcon: ({ color, size }) => (
                <MaterialIcons color={color} name="search" size={size} />
              ),
            }}
          />
          <Tabs.Screen
            name="profile"
            options={{
              title: "Profile",
              tabBarIcon: ({ color, size }) => (
                <MaterialIcons color={color} name="person" size={size} />
              ),
            }}
          />
        </Tabs>
      </SafeAreaProvider>
    </GestureHandlerRootView>
  );
}
The tabBar prop receives the navigation props from Expo Router and passes them straight through to JellyTabBar — there is nothing else to wire up.
The floating prop positions the tab bar over the screen content instead of reserving layout space below it. The active screen fills the full height of the display, behind the bar. If your screen is scrollable, add enough bottom content padding (equal to the bar height, default 64 dp) so the last item remains reachable above the floating bar.
4

Run the app

Start your development server and launch the app on your target platform:
# iOS simulator
npx expo run:ios

# Android emulator or device
npx expo run:android

# Web browser
npx expo start --web
Tap between tabs to see the jelly snap animation. Drag the pill to scrub between tabs in real time.

What’s next

If you are using a custom router or managing your own navigation state, JellyTabBarHeadless gives you the full animated component without any navigation integration. Pass an items array, a selectedIndex, and an onTabPress handler — Jelly Tabs handles the rest. See the headless guide for details.

Build docs developers (and LLMs) love