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
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>
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'
}
});
Modal with Blur Background
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 | Blur Effect | Fallback |
|---|
| iOS | ✅ Native | - |
| Android | 🚧 Experimental | Semi-transparent overlay |
| Web | ✅ CSS backdrop-filter | Semi-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
- Use Overflow Hidden: Always add
overflow: 'hidden' to parent containers with borderRadius
- Performance: Blur effects can be expensive on Android; use sparingly
- Intensity: Start with 80-90 intensity for good visual effect
- Tint Selection: Match tint with content color (dark tint for light text)
- Test on Android: Always test Android fallback appearance
Avoid animating BlurView intensity or nesting multiple BlurViews, as this can cause performance issues.
Resources