Skip to main content

expo-blur

Version: 55.0.6 A component that renders a native blur view on iOS and falls back to a semi-transparent view on Android. Commonly used for navigation bars, tab bars, and modals.

Installation

npx expo install expo-blur

Usage

import { BlurView } from 'expo-blur';
import { Text, StyleSheet } from 'react-native';

function App() {
  return (
    <BlurView intensity={80} style={styles.blurContainer}>
      <Text>Content with blur background</Text>
    </BlurView>
  );
}

const styles = StyleSheet.create({
  blurContainer: {
    padding: 20,
    borderRadius: 10
  }
});

API Reference

BlurView Props

intensity
number
default:"50"
Blur intensity from 0 (no blur) to 100 (maximum blur)
<BlurView intensity={80}>
  <Text>Blurred content</Text>
</BlurView>
tint
'light' | 'dark' | 'default' | 'extraLight' | 'regular' | 'prominent' | 'systemMaterial' | 'systemThickMaterial' | 'systemThinMaterial' | 'systemUltraThinMaterial' | 'systemChromeMaterial'
default:"default"
Tint style for the blur effect
  • light: Light blur (iOS: light, Android: white overlay)
  • dark: Dark blur (iOS: dark, Android: dark overlay)
  • default: System default
  • Material styles: iOS 13+ specific blur materials
<BlurView tint="dark" intensity={80}>
  <Text style={{ color: 'white' }}>Dark blur</Text>
</BlurView>
style
ViewStyle
Standard React Native view style
<BlurView style={{ flex: 1, padding: 20 }} />
experimentalBlurMethod
'none' | 'dimezisBlurView'
Android only: Experimental blur implementation
  • none: Default semi-transparent overlay
  • dimezisBlurView: Real blur effect (experimental)
<BlurView 
  experimentalBlurMethod="dimezisBlurView"
  intensity={80}
/>

Examples

Basic Blur Overlay

import { BlurView } from 'expo-blur';
import { ImageBackground, Text, StyleSheet } from 'react-native';

function App() {
  return (
    <ImageBackground 
      source={require('./background.jpg')} 
      style={styles.background}
    >
      <BlurView intensity={90} style={styles.blurContainer}>
        <Text style={styles.text}>Blurred Overlay</Text>
      </BlurView>
    </ImageBackground>
  );
}

const styles = StyleSheet.create({
  background: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  blurContainer: {
    padding: 40,
    borderRadius: 20,
    overflow: 'hidden'
  },
  text: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#000'
  }
});

Light and Dark Blur

import { BlurView } from 'expo-blur';
import { View, Text, StyleSheet } from 'react-native';

function BlurExample() {
  return (
    <View style={styles.container}>
      <BlurView intensity={80} tint="light" style={styles.blur}>
        <Text style={styles.darkText}>Light Blur</Text>
      </BlurView>
      
      <BlurView intensity={80} tint="dark" style={styles.blur}>
        <Text style={styles.lightText}>Dark Blur</Text>
      </BlurView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    gap: 20
  },
  blur: {
    padding: 20,
    borderRadius: 10,
    overflow: 'hidden'
  },
  darkText: {
    color: '#000',
    fontSize: 18
  },
  lightText: {
    color: '#fff',
    fontSize: 18
  }
});

Bottom Tab Bar

import { BlurView } from 'expo-blur';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';

function TabBar() {
  return (
    <BlurView intensity={95} tint="light" style={styles.tabBar}>
      <TouchableOpacity style={styles.tab}>
        <Text>🏠</Text>
        <Text style={styles.tabLabel}>Home</Text>
      </TouchableOpacity>
      
      <TouchableOpacity style={styles.tab}>
        <Text>🔍</Text>
        <Text style={styles.tabLabel}>Search</Text>
      </TouchableOpacity>
      
      <TouchableOpacity style={styles.tab}>
        <Text>⚙️</Text>
        <Text style={styles.tabLabel}>Settings</Text>
      </TouchableOpacity>
    </BlurView>
  );
}

const styles = StyleSheet.create({
  tabBar: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    flexDirection: 'row',
    paddingVertical: 10,
    paddingHorizontal: 20,
    borderTopWidth: StyleSheet.hairlineWidth,
    borderTopColor: 'rgba(0,0,0,0.1)'
  },
  tab: {
    flex: 1,
    alignItems: 'center',
    gap: 4
  },
  tabLabel: {
    fontSize: 12,
    color: '#000'
  }
});
import { BlurView } from 'expo-blur';
import { Modal, View, Text, Button, StyleSheet } from 'react-native';
import { useState } from 'react';

function App() {
  const [visible, setVisible] = useState(false);

  return (
    <View style={styles.container}>
      <Button title="Show Modal" onPress={() => setVisible(true)} />
      
      <Modal
        visible={visible}
        transparent
        animationType="fade"
        onRequestClose={() => setVisible(false)}
      >
        <BlurView intensity={90} tint="dark" style={styles.modalBackground}>
          <View style={styles.modalContent}>
            <Text style={styles.modalTitle}>Modal Title</Text>
            <Text style={styles.modalText}>This is a modal with blurred background</Text>
            <Button title="Close" onPress={() => setVisible(false)} />
          </View>
        </BlurView>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  modalBackground: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  modalContent: {
    backgroundColor: 'white',
    padding: 30,
    borderRadius: 20,
    gap: 15,
    minWidth: 300
  },
  modalTitle: {
    fontSize: 24,
    fontWeight: 'bold'
  },
  modalText: {
    fontSize: 16
  }
});
import { BlurView } from 'expo-blur';
import { View, Text, StyleSheet, SafeAreaView } from 'react-native';

function Screen() {
  return (
    <View style={styles.container}>
      <BlurView intensity={95} tint="light" style={styles.header}>
        <SafeAreaView>
          <View style={styles.headerContent}>
            <Text style={styles.headerTitle}>Screen Title</Text>
          </View>
        </SafeAreaView>
      </BlurView>
      
      {/* Screen content */}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  header: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    zIndex: 10,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: 'rgba(0,0,0,0.1)'
  },
  headerContent: {
    height: 44,
    justifyContent: 'center',
    alignItems: 'center'
  },
  headerTitle: {
    fontSize: 17,
    fontWeight: '600',
    color: '#000'
  }
});

Card with Blur Effect

import { BlurView } from 'expo-blur';
import { ImageBackground, Text, StyleSheet } from 'react-native';

function Card() {
  return (
    <ImageBackground 
      source={require('./card-bg.jpg')} 
      style={styles.card}
      imageStyle={styles.cardImage}
    >
      <BlurView intensity={70} tint="dark" style={styles.cardContent}>
        <Text style={styles.cardTitle}>Card Title</Text>
        <Text style={styles.cardDescription}>
          This card has a blurred background overlay
        </Text>
      </BlurView>
    </ImageBackground>
  );
}

const styles = StyleSheet.create({
  card: {
    width: '100%',
    height: 200,
    borderRadius: 15,
    overflow: 'hidden'
  },
  cardImage: {
    borderRadius: 15
  },
  cardContent: {
    flex: 1,
    padding: 20,
    justifyContent: 'flex-end'
  },
  cardTitle: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#fff',
    marginBottom: 8
  },
  cardDescription: {
    fontSize: 14,
    color: '#fff',
    opacity: 0.9
  }
});

iOS Material Styles

import { BlurView } from 'expo-blur';
import { ScrollView, View, Text, StyleSheet } from 'react-native';

function MaterialShowcase() {
  const materials: Array<{
    tint: any;
    label: string;
  }> = [
    { tint: 'systemMaterial', label: 'System Material' },
    { tint: 'systemThickMaterial', label: 'Thick Material' },
    { tint: 'systemThinMaterial', label: 'Thin Material' },
    { tint: 'systemUltraThinMaterial', label: 'Ultra Thin' },
    { tint: 'systemChromeMaterial', label: 'Chrome Material' },
  ];

  return (
    <ScrollView style={styles.container}>
      {materials.map((material) => (
        <BlurView 
          key={material.label}
          intensity={100} 
          tint={material.tint}
          style={styles.materialCard}
        >
          <Text style={styles.materialLabel}>{material.label}</Text>
        </BlurView>
      ))}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20
  },
  materialCard: {
    padding: 20,
    marginBottom: 15,
    borderRadius: 10,
    overflow: 'hidden'
  },
  materialLabel: {
    fontSize: 16,
    fontWeight: '600'
  }
});

TypeScript

import { BlurView } from 'expo-blur';
import type { BlurTint } from 'expo-blur';

const tint: BlurTint = 'dark';
const intensity: number = 80;

<BlurView tint={tint} intensity={intensity} />;

Platform Support

PlatformBlur EffectFallback
iOS✅ Native-
Android🚧 ExperimentalSemi-transparent overlay
Web✅ CSS backdrop-filterSemi-transparent overlay
iOS: Uses UIVisualEffectView for native blurAndroid: By default, renders a semi-transparent view. Use experimentalBlurMethod="dimezisBlurView" for real blur (may have performance issues)Web: Uses CSS backdrop-filter with fallback for unsupported browsers

Best Practices

  1. Use Overflow Hidden: Always add overflow: 'hidden' to parent containers with borderRadius
  2. Performance: Blur effects can be expensive on Android; use sparingly
  3. Intensity: Start with 80-90 intensity for good visual effect
  4. Tint Selection: Match tint with content color (dark tint for light text)
  5. Test on Android: Always test Android fallback appearance
Avoid animating BlurView intensity or nesting multiple BlurViews, as this can cause performance issues.

Resources