diff --git a/with-native-tabs/README.md b/with-native-tabs/README.md
new file mode 100644
index 00000000..48dd63ff
--- /dev/null
+++ b/with-native-tabs/README.md
@@ -0,0 +1,50 @@
+# Welcome to your Expo app 👋
+
+This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
+
+## Get started
+
+1. Install dependencies
+
+ ```bash
+ npm install
+ ```
+
+2. Start the app
+
+ ```bash
+ npx expo start
+ ```
+
+In the output, you'll find options to open the app in a
+
+- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
+- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
+- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
+- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
+
+You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
+
+## Get a fresh project
+
+When you're ready, run:
+
+```bash
+npm run reset-project
+```
+
+This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
+
+## Learn more
+
+To learn more about developing your project with Expo, look at the following resources:
+
+- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
+- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
+
+## Join the community
+
+Join our community of developers creating universal apps.
+
+- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
+- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.
diff --git a/with-native-tabs/app.json b/with-native-tabs/app.json
new file mode 100644
index 00000000..19a4cece
--- /dev/null
+++ b/with-native-tabs/app.json
@@ -0,0 +1,10 @@
+{
+ "expo": {
+ "name": "with-native-tabs",
+ "slug": "with-native-tabs",
+ "orientation": "default",
+ "scheme": "withnativetabs",
+ "userInterfaceStyle": "automatic",
+ "plugins": ["expo-router"]
+ }
+}
diff --git a/with-native-tabs/app/_layout.tsx b/with-native-tabs/app/_layout.tsx
new file mode 100644
index 00000000..ca4ade61
--- /dev/null
+++ b/with-native-tabs/app/_layout.tsx
@@ -0,0 +1,79 @@
+import MaterialIcons from "@expo/vector-icons/MaterialCommunityIcons";
+import {
+ Badge,
+ Icon,
+ Label,
+ NativeTabs,
+ VectorIcon,
+} from "expo-router/unstable-native-tabs";
+import { Platform, useColorScheme, View } from "react-native";
+import {
+ DarkTheme,
+ DefaultTheme,
+ ThemeProvider,
+} from "@react-navigation/native";
+import { TabConfigurationContext } from "@/utils/tabConfigurationContext";
+import { useState } from "react";
+
+export default function RootLayout() {
+ const scheme = useColorScheme();
+ const [isMinimizeOnScrollEnabled, setIsMinimizeOnScrollEnabled] =
+ useState(true);
+ const [isIndicatorEnabled, setIsIndicatorEnabled] = useState(true);
+ const [
+ isTransparentOnScrollEdgeEnabled,
+ setIsTransparentOnScrollEdgeEnabled,
+ ] = useState(true);
+
+ return (
+
+
+
+
+
+ }
+ />
+
+
+
+ 3
+ }
+ />
+
+
+
+
+ }
+ />
+
+
+
+
+ );
+}
diff --git a/with-native-tabs/app/explore.tsx b/with-native-tabs/app/explore.tsx
new file mode 100644
index 00000000..7c6a202c
--- /dev/null
+++ b/with-native-tabs/app/explore.tsx
@@ -0,0 +1,170 @@
+import { TabConfigurationContext } from "@/utils/tabConfigurationContext";
+import { useTheme } from "@react-navigation/native";
+import {
+ Badge,
+ Icon,
+ Label,
+ NativeTabs,
+} from "expo-router/unstable-native-tabs";
+import { use, useState } from "react";
+import {
+ View,
+ Text,
+ StyleSheet,
+ ScrollView,
+ Switch,
+ Platform,
+} from "react-native";
+import {
+ SafeAreaInsetsContext,
+ useSafeAreaInsets,
+} from "react-native-safe-area-context";
+
+export default function Index() {
+ const { colors } = useTheme();
+ const safeInsets = useSafeAreaInsets();
+ const [isBadgeEnabled, setIsBadgeEnabled] = useState(true);
+ const [isLabelVisible, setIsLabelVisible] = useState(true);
+ const [isScrollToTopEnabled, setIsScrollToTopEnabled] = useState(true);
+ const {
+ isMinimizeOnScrollEnabled,
+ setIsMinimizeOnScrollEnabled,
+ isIndicatorEnabled,
+ setIsIndicatorEnabled,
+ isTransparentOnScrollEdgeEnabled,
+ setIsTransparentOnScrollEdgeEnabled,
+ } = use(TabConfigurationContext);
+ return (
+ <>
+
+
+
+
+
+
+
+
+ Scroll
+ down
+ \/
+ This
+
+ content
+
+ is
+ here
+ to
+ test
+
+ scrolling
+
+ It
+ needs
+ to
+ be
+ long,
+ to
+ enable
+
+ minimize
+
+
+ behavior
+
+
+
+
+ 3
+
+
+ >
+ );
+}
+
+const SwitchWithLabel = ({
+ label,
+ value,
+ onValueChange,
+}: {
+ label: string;
+ value: boolean;
+ onValueChange: (value: boolean) => void;
+}) => {
+ const { colors } = useTheme();
+ return (
+
+ {label}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ contentContainer: {
+ paddingHorizontal: 16,
+ gap: 16,
+ },
+ largeContent: {
+ marginTop: 96,
+ gap: 48,
+ alignItems: "center",
+ },
+ text: {
+ fontSize: 20,
+ },
+ largeText: {
+ fontSize: 48,
+ },
+});
diff --git a/with-native-tabs/app/index.tsx b/with-native-tabs/app/index.tsx
new file mode 100644
index 00000000..5a3002f2
--- /dev/null
+++ b/with-native-tabs/app/index.tsx
@@ -0,0 +1,22 @@
+import { useTheme } from "@react-navigation/native";
+import { View, Text, StyleSheet, PlatformColor } from "react-native";
+
+export default function Index() {
+ const { colors } = useTheme();
+ return (
+
+ Home tab
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ text: {
+ fontSize: 20,
+ },
+});
diff --git a/with-native-tabs/app/search/[name].tsx b/with-native-tabs/app/search/[name].tsx
new file mode 100644
index 00000000..60fa2c7b
--- /dev/null
+++ b/with-native-tabs/app/search/[name].tsx
@@ -0,0 +1,31 @@
+import { useTheme } from "@react-navigation/native";
+import { Stack, useLocalSearchParams } from "expo-router";
+import { StyleSheet, Text, View } from "react-native";
+
+export default function Page() {
+ const { colors } = useTheme();
+ const { name } = useLocalSearchParams<{ name: string }>();
+ return (
+ <>
+
+
+ {name}
+
+ >
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ label: {
+ fontSize: 24,
+ },
+});
diff --git a/with-native-tabs/app/search/_layout.tsx b/with-native-tabs/app/search/_layout.tsx
new file mode 100644
index 00000000..d5062f71
--- /dev/null
+++ b/with-native-tabs/app/search/_layout.tsx
@@ -0,0 +1,17 @@
+import { isLiquidGlassAvailable } from "expo-glass-effect";
+import { Stack } from "expo-router";
+
+export default function SearchLayout() {
+ return (
+
+
+
+ );
+}
diff --git a/with-native-tabs/app/search/index.tsx b/with-native-tabs/app/search/index.tsx
new file mode 100644
index 00000000..02707ff1
--- /dev/null
+++ b/with-native-tabs/app/search/index.tsx
@@ -0,0 +1,76 @@
+import { useTheme } from "@react-navigation/native";
+import { Link, Stack } from "expo-router";
+import { useMemo, useState } from "react";
+import { StyleSheet, ScrollView, Text } from "react-native";
+
+const fruits = [
+ "apple",
+ "banana",
+ "cherry",
+ "date",
+ "elderberry",
+ "fig",
+ "grape",
+ "honeydew",
+ "kiwi",
+ "lemon",
+ "mango",
+ "nectarine",
+];
+
+const adjectives = [
+ "fresh",
+ "ripe",
+ "juicy",
+ "sweet",
+ "delicious",
+ "tasty",
+ "zesty",
+];
+
+const results = fruits.flatMap((fruit) =>
+ adjectives.map((adj) => `${adj} ${fruit}`)
+);
+
+export default function Index() {
+ const { colors } = useTheme();
+ const [searchQuery, setSearchQuery] = useState("");
+ const data = useMemo(
+ () =>
+ results.filter((result) =>
+ result.toLowerCase().includes(searchQuery.toLowerCase())
+ ),
+ [searchQuery]
+ );
+ return (
+ <>
+ setSearchQuery(e.nativeEvent.text),
+ },
+ }}
+ />
+
+ {data.map((result, index) => (
+
+ {result}
+
+ ))}
+
+ >
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ text: {
+ fontSize: 20,
+ padding: 4,
+ },
+});
diff --git a/with-native-tabs/eslint.config.js b/with-native-tabs/eslint.config.js
new file mode 100644
index 00000000..5025da68
--- /dev/null
+++ b/with-native-tabs/eslint.config.js
@@ -0,0 +1,10 @@
+// https://docs.expo.dev/guides/using-eslint/
+const { defineConfig } = require('eslint/config');
+const expoConfig = require('eslint-config-expo/flat');
+
+module.exports = defineConfig([
+ expoConfig,
+ {
+ ignores: ['dist/*'],
+ },
+]);
diff --git a/with-native-tabs/package.json b/with-native-tabs/package.json
new file mode 100644
index 00000000..8916c2bd
--- /dev/null
+++ b/with-native-tabs/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "with-native-tabs",
+ "main": "expo-router/entry",
+ "version": "1.0.0",
+ "scripts": {
+ "start": "expo start"
+ },
+ "dependencies": {
+ "@expo/vector-icons": "^15.0.3",
+ "@react-navigation/native": "^7.1.19",
+ "expo": "~54.0.20",
+ "expo-constants": "~18.0.10",
+ "expo-glass-effect": "~0.1.4",
+ "expo-router": "~6.0.13",
+ "expo-splash-screen": "^31.0.10",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
+ "react-native": "0.81.5",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.16.0",
+ "react-native-web": "~0.21.0"
+ },
+ "devDependencies": {
+ "@types/react": "~19.1.0",
+ "typescript": "~5.9.2"
+ }
+}
diff --git a/with-native-tabs/tsconfig.json b/with-native-tabs/tsconfig.json
new file mode 100644
index 00000000..fc3e1466
--- /dev/null
+++ b/with-native-tabs/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "extends": "expo/tsconfig.base",
+ "compilerOptions": {
+ "strict": true,
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ }
+ },
+ "include": [
+ "**/*.ts",
+ "**/*.tsx"
+ ]
+}
diff --git a/with-native-tabs/utils/tabConfigurationContext.ts b/with-native-tabs/utils/tabConfigurationContext.ts
new file mode 100644
index 00000000..16e6393e
--- /dev/null
+++ b/with-native-tabs/utils/tabConfigurationContext.ts
@@ -0,0 +1,17 @@
+import { createContext, type Dispatch, type SetStateAction } from "react";
+
+export const TabConfigurationContext = createContext<{
+ isMinimizeOnScrollEnabled: boolean;
+ setIsMinimizeOnScrollEnabled: Dispatch>;
+ isIndicatorEnabled: boolean;
+ setIsIndicatorEnabled: Dispatch>;
+ isTransparentOnScrollEdgeEnabled: boolean;
+ setIsTransparentOnScrollEdgeEnabled: Dispatch>;
+}>({
+ isMinimizeOnScrollEnabled: true,
+ setIsMinimizeOnScrollEnabled: () => {},
+ isIndicatorEnabled: true,
+ setIsIndicatorEnabled: () => {},
+ isTransparentOnScrollEdgeEnabled: true,
+ setIsTransparentOnScrollEdgeEnabled: () => {},
+});