The video introduces native tabs functionality in Expo Router v6 (SDK 54+), highlighting the transition from JavaScript tabs to fully native tabs on iOS and Android. Key features discussed include liquid glass tabs for iOS, Android popovers, scroll-to-top, badges, and dark mode support.
"Unlike JavaScript tabs, this uses the system native tabs on both iOS and Android."
expo router/unstable/native-tabs.SF house.fill for icons."It's powerful, but not a drop-in replacement for the old JavaScript tabs."
The video effectively demonstrates the transition to native tabs in Expo, emphasizing the benefits and aesthetic improvements, particularly with the liquid glass effect. The structured tutorial format aids viewers in understanding both the implementation steps and the potential limitations of this new feature. The encouragement for feedback indicates an ongoing development process, inviting the community to contribute to the feature's evolution.
Native tabs are one of the most common navigation patterns in mobile applications. But until now, React Native applications have mostly relied on JavaScript implementations. Today, I'm excited to share with you the new native tabs beta in Expo Router version 6. Unlike JavaScript tabs, this use the system native tabs on both iOS and Android. On iOS 26 and above, you'll see the new liquid glass effect that adapts beautifully to any background. On older iOS versions, you'll just get the classic default look. On Android, the implementation is also fully native, and you'll get the platform specific features like a popover showing the screen name when you long press a tab. That's Android only. Now, this feature is still experimental, available only on SDK 54 and above. And you'll notice that we imported from expo router/unstable native tabs. That unstable prefix means that the API might change before it comes stable. But the benefit is that you get first access to native features like liquid glass tabs on iOS 26 and above. And also notice that you need Xcode 26 if you want to test liquid glass. Automatic scroll to top when pressing a tab that's already active. Up to root behavior by default when reselecting the same tab. That means if the user was on a different stack screen when they press the home tab they will navigate to to the root home screen for example and many more native effects that make your application feel a first class citizen on both platforms. Now let's dive in and see how we can use native tabs. Let's start by creating a new expo app using the default template @next. And this is because at the time that I'm recording this video, Expo SK54 is in beta. So to use the template with that version, we need to say at next. But if Expo SDK 54 is out at the time that I'm that you are watching this video, just run it without the @next. Right? So let's hit enter. This will ask me the name of my application, Native Tabs Video, and hit enter. Okay. And my app is ready. Now let's cd and you can open this in VS code or your preferred IDE. So here's my app. Let's double check that we are using Expo SDK 54. So this is my package JSON. I'm using the version 54. Expo router version 6 and above. Make sure to have these two versions. And you need React Native Screens version 4.16.0 or above. Okay. So this is actually being added to the template at the time that I'm recording this video. So I'm going to do this manually here. And let's open my terminal and install dependencies again by saying bun install. Let's start the server. npx expo start. Hit enter. All right. And now let's run this on iOS. With Expo 54 Expo now comes with support for native tabs. But at the time uh you are looking at the JavaScript implementation. Let me run this on Android to show you how it looks. All right, this is how it looks on Android. At the time we are using the default JavaScript tabs, but let's see how we can use the native tabs. Let's open the layouts where the tabs are. And here you can see that right now we are using the JavaScript tabs. So let's remove these tabs from here. And I'm going to say /unstable native tabs. All right. Now let's come here and we can import native tabs icon and label. We can also import batch by the way. So let's hit save. All right. Now everything is going to break of course because now we need to replace what we have in here. Instead of using these tabs, the previous ones, now we're going to say native tabs. Let's go down here and say native tabs as well. And then let me comment these two. I'm going to say native tabs.trigger. And then I'm going to pass a label. Let's say home. Now the trigger needs a name, the name of the route. In this case, it's going to be index. Okay, let me refresh the application. Awesome. And now it's working again, but we don't have an icon. So let's add that that icon here. The icon is coming from the native tabs as well. And you can pass a San Francisco icon by saying SF house.fill - Awesome. Now I have my home icon. Now this will only work for iOS because if I go right now to my Android app and let's refresh. Let's see how this looks on Android. As you can see, we don't have an icon for Android. And for Android, we need to pass a drawable. If we take a look at the documentation, by the way, I'm going to leave the link in the description here. You can see that for Android we can use a drawable. And Android comes with some built-in drawables or you can create a custom one. You can learn more about the default ones here. There's a link with a list of icons that you can use. So for my application in this case, I'm going to say menu my location and hit save. Now let's see how this looks on Android. Okay, now I have an icon. Again, this is fully native. For example, on Android, if you long press on the tab, you'll get that popover with the name of the screen. Now, we can actually go ahead and delete this. And since the native tabs handle dark mode automatically, we don't need to have this anymore. And you'll notice that your component is cleaner now. Now, let's create a tab for the explore section. So, I'm just going to duplicate this, paste it in here, hit save. Of course, we need a different name. In this case, is going to be explore. Hit save. And let me refresh. Okay, awesome. Now, of course, the label is going to be explore. And in this case, I want to use the gear. And here we have the full list of icons that we can use, right? So, that looks really nice. For Android, I'm going to use the one menu manage. See how that looks. Is that little wrench? Awesome. Everything looks very nice. Let's long press. Awesome. To use the batch, you can just pass it like this. Let's copy this and let's put it in the settings right here. Hit save. And that's a batch. Let's see how that looks on Android. Awesome. Now let's toggle dark mode. And we can see that the tabs react seamlessly. Now if I open all these expandables and scroll all the way down. When I press the tab, this is one of the native features. When I press the same tab again, this is going to scroll up automatically, which is really cool. Now you might be wondering where is the liquid glass on iOS since this one has actually iOS 26. The reason why it's not showing on ExpoGo is because Expo was compiled with Xcode 16. So if we want to see the liquid glass tabs, we need to compile this project with Xcode 26. So I already have installed Xcode 26 and I'm going to stop this and of course I need to create a development build. So let's pre-build the project. This will be only for iOS. This is going to generate the iOS folder on the left. Once we have that, we can run it on the simulator by saying npx expo run iOS. Okay, the build is ready. Same device, but now the application is compiled with Xcode 26. Let's open it. And just like that, we get the liquid glass. Here we have it. Looks really cool. And of course, they work seamlessly on any background and adapt to dark mode as well. We also have the native behavior scroll to top when I press the tab. And by the way, you can disable that if you want to by going to the tab by saying disable scroll to top. You'll notice as well that for iOS you can disable pop to top. Let's put this in here. And now if I try to do the same thing again, let me open this, scroll all the way down and if I press it now it's disabled. Most of the time you are going to need that to be enabled. I think that's expected nowadays on modern applications. Press it. Boom. One little warning here is that since this is still in beta, there are a few limitations to be aware of. On Android, you are limited to five tabs. There's no custom image support yet for Android. Nested tabs aren't supported yet, and you can't measure the tab bar height directly for now. So, it's powerful, but not a drop in replacement for the old JavaScript tabs. So, if you need more custom behavior, stick with the JavaScript implementation. Native tabs are one step closer to making Expo applications feel even more polished and platform native out of the box. Try them today with Expo Router version 6 and Expo SDK 54 or later, and let us know what you think. At the moment, the API is unstable, but your feedback will help us shape the the final design before we remove the unstable prefix. And as always, if you find this video helpful, don't forget to like, subscribe, and check out the links in the description for more Expo Router tutorials. See you in the next one.
Native tabs are here in Expo Router v6 (SDK 54+). Learn how to replace JavaScript tabs with fully native ones on iOS and Android. See features like liquid glass tabs on iOS 26+, Android popovers, scroll-to-top, badges, dark mode support, and more. In this step-by-step tutorial, we’ll set up native tabs, customize icons, and explore limitations you should know before going stable. Docs: https://docs.expo.dev/router/advanced/native-tabs Expo Router v6 blog: https://expo.dev/blog/expo-router-v6 Liquid Glass blog: https://expo.dev/blog/liquid-glass-app-with-expo-ui-and-swiftui ⏱️ Timestamps 01:40 – Creating a new app 02:20 – Double checking required versions 03:18 – Implementing Native Tabs 04:26 – Adding iOS Icons 04:45 – Android Icons 05:32 – Removing old implementation 05:46 – Adding more tabs 06:29 – Adding Tab Badges 06:44 – Testing Native Features 07:03 – Liquid Glass Tabs 08:12 – Tabs Options 08:46 – Limitations 09:12 – Recap #Expo #ReactNative #liquidglass