NativeTabs renders truly native tab bars on iOS via UITabBarController, but that means there's no JS-level tabPress listener, so no haptic feedback out of the box. The fix: patch expo-router with bun patch.
Update: The latest version of NativeTabs now exposes a screenListeners prop, so you can add haptics without patching:
The file uses CommonJS with __importStar (TypeScript-generated), match that style.
4. Add the haptic trigger
Find the onTabChange callback and add the haptics call at the top:
const onTabChange = (0, react_1.useCallback)((tabKey) => { if (process.env.EXPO_OS === 'ios') { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); } const descriptor = descriptors[tabKey]; // ...rest of the function
Light impact feels subtle and native for frequent tab taps. The EXPO_OS guard keeps it iOS-only since NativeTabs only renders there.
5. Commit the patch
bun patch --commit 'node_modules/expo-router'
Bun generates the .patch file in patches/ and updates package.json automatically, no manual patchedDependencies editing needed.
6. Verify
Run bun install, you should see the patch apply. Build on a physical iOS device (haptics don't work on simulator) and feel the tap on every tab switch.
One import, four lines in the callback. Small patch, big UX win.
Tips
Patch the build/ files, not TypeScript source, Metro loads the compiled JS.
Re-generate the patch when you upgrade expo-router, line numbers will shift.
Check upstream before upgrading, Expo may add haptics to NativeTabs natively.
Want to go deeper?
This patch came straight from Inkigo, a real, shipped app on the App Store. If you're curious how it feels in practice, download it and tap through the tabs.
Pro Members get access to the full Inkigo source code, along with many other premium resources, including all my courses.
If you want to go beyond quick patches and really understand how to build apps that feel native, my React Native course covers advanced Expo Router patterns, platform-specific details, and the kind of polish that separates side projects from shipped products.
I also share practical tips, experiments, and updates in my newsletter if you want to stay in the loop.