React Native Blur

Frosted glass header and tab bar in React Native

A sticky header or floating tab bar that blurs the list scrolling under it, the way iOS navigation bars do, with the same look on Android.

GitHubnpmChangelogllms.txt

Backdrop blur on iOS and Android: a frosted sticky header over a scrolling list, a frosted popup over a map and a frosted button over a video
Backdrop mode on iOS (left) and Android (right).

Install

React Native CLI

npm install @nguyenduy1412/react-native-blur
cd ios && pod install

Rebuild the app. Autolinking picks the library up; no Expo packages are needed.

Expo

npx expo install @nguyenduy1412/react-native-blur
npx expo run:ios
npx expo run:android

It contains native code, so it does not run in Expo Go. Use a development build or EAS Build.

Sticky header over a scrolling list

Put the list first and the header after it, absolutely positioned. mode="backdrop" blurs whatever is drawn behind the header, and the title stays sharp.

import BlurView from "@nguyenduy1412/react-native-blur";
import { useSafeAreaInsets } from "react-native-safe-area-context";

export function Inbox({ items }) {
  const insets = useSafeAreaInsets();
  return (
    <View style={{ flex: 1 }}>
      <ScrollView contentContainerStyle={{ paddingTop: insets.top + 56 }}>{items}</ScrollView>

      <BlurView
        mode="backdrop"
        intensity={85}
        tint="systemMaterial"
        style={{ position: "absolute", top: 0, left: 0, right: 0, paddingTop: insets.top, paddingBottom: 12 }}
      >
        <Text style={{ fontSize: 17, fontWeight: "600", textAlign: "center" }}>Inbox</Text>
      </BlurView>
    </View>
  );
}

Floating glass tab bar

<BlurView
  mode="backdrop"
  intensity={80}
  tint="systemThinMaterial"
  style={{ position: "absolute", left: 16, right: 16, bottom: 24, borderRadius: 32, flexDirection: "row" }}
>
  {tabs}
</BlurView>

React Navigation tab bar background

Use the BlurView as the tab bar background and make the tab bar transparent and absolute so screens scroll under it.

<Tab.Navigator
  screenOptions={{
    tabBarStyle: { position: "absolute", backgroundColor: "transparent", borderTopWidth: 0 },
    tabBarBackground: () => (
      <BlurView mode="backdrop" intensity={80} tint="systemChromeMaterial" style={StyleSheet.absoluteFill} />
    ),
  }}
>
  {/* screens */}
</Tab.Navigator>

Which tint to use

All system* materials follow light and dark mode on both platforms.

FAQ

Why does my header show only a grey tint on Android?

Use mode="backdrop". The default content mode blurs the view's own children, and a header has nothing of its own to blur. Real blur also needs Android 12 (API 31)+.

Does the header blur stay in sync while scrolling?

Yes. On Android the backdrop recording is refreshed on every frame where something changed, including scroll offsets. On iOS it is the system UIVisualEffectView.

Does it work in Expo Go?

No. The package contains native code, so it needs a development build (npx expo run:ios / npx expo run:android) or EAS Build. React Native CLI apps work after pod install and a rebuild.

Does it work without Expo?

Yes. Since 2.0 it is a plain React Native Fabric component, so a React Native CLI app only needs npm install and pod install.

Which Android versions get a real blur?

Android 12 (API 31) and later, where RenderEffect exists. Android 11 and earlier draw a translucent material plate without blur, so content stays readable.