expo-haptics
Version: 55.0.6
Provides access to the system’s haptics engine on iOS, vibration effects on Android, and Web Vibration API on web.
Installation
npx expo install expo-haptics
Usage
import * as Haptics from 'expo-haptics';
// Light impact
await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
// Success notification
await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
// Selection feedback
await Haptics.selectionAsync();
API Reference
Impact Feedback
Haptics.impactAsync(style)
(style: ImpactFeedbackStyle) => Promise<void>
Triggers impact haptic feedbackStyles:
Haptics.ImpactFeedbackStyle.Light
Haptics.ImpactFeedbackStyle.Medium
Haptics.ImpactFeedbackStyle.Heavy
Haptics.ImpactFeedbackStyle.Rigid (iOS 13+)
Haptics.ImpactFeedbackStyle.Soft (iOS 13+)
await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
Notification Feedback
Haptics.notificationAsync(type)
(type: NotificationFeedbackType) => Promise<void>
Triggers notification haptic feedbackTypes:
Haptics.NotificationFeedbackType.Success
Haptics.NotificationFeedbackType.Warning
Haptics.NotificationFeedbackType.Error
await Haptics.notificationAsync(
Haptics.NotificationFeedbackType.Success
);
Selection Feedback
Triggers selection change haptic feedback// Use when user changes a selection (e.g., picker wheel)
await Haptics.selectionAsync();
Examples
import * as Haptics from 'expo-haptics';
import { TouchableOpacity, Text } from 'react-native';
function HapticButton() {
const handlePress = async () => {
await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
// Handle button action
};
return (
<TouchableOpacity onPress={handlePress}>
<Text>Press Me</Text>
</TouchableOpacity>
);
}
import * as Haptics from 'expo-haptics';
import { useState } from 'react';
import { TextInput, Button } from 'react-native';
function Form() {
const [email, setEmail] = useState('');
const handleSubmit = async () => {
if (!email.includes('@')) {
await Haptics.notificationAsync(
Haptics.NotificationFeedbackType.Error
);
alert('Invalid email');
return;
}
await Haptics.notificationAsync(
Haptics.NotificationFeedbackType.Success
);
// Submit form
};
return (
<>
<TextInput value={email} onChangeText={setEmail} />
<Button title="Submit" onPress={handleSubmit} />
</>
);
}
Picker Selection
import * as Haptics from 'expo-haptics';
import { useState } from 'react';
import { Picker } from '@react-native-picker/picker';
function PickerWithHaptics() {
const [selected, setSelected] = useState('option1');
const handleValueChange = async (value: string) => {
await Haptics.selectionAsync();
setSelected(value);
};
return (
<Picker selectedValue={selected} onValueChange={handleValueChange}>
<Picker.Item label="Option 1" value="option1" />
<Picker.Item label="Option 2" value="option2" />
<Picker.Item label="Option 3" value="option3" />
</Picker>
);
}
Different Impact Levels
import * as Haptics from 'expo-haptics';
import { View, Button } from 'react-native';
function HapticDemo() {
return (
<View style={{ gap: 10 }}>
<Button
title="Light Impact"
onPress={() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)}
/>
<Button
title="Medium Impact"
onPress={() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium)}
/>
<Button
title="Heavy Impact"
onPress={() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy)}
/>
<Button
title="Success"
onPress={() => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)}
/>
<Button
title="Warning"
onPress={() => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning)}
/>
<Button
title="Error"
onPress={() => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error)}
/>
</View>
);
}
| Platform | Haptics | Vibration |
|---|
| iOS | ✅ UIFeedbackGenerator | ✅ |
| Android | ✅ VibrationEffect | ✅ |
| Web | ✅ Vibration API | ✅ |
iOS: Uses UIImpactFeedbackGenerator, UINotificationFeedbackGenerator, and UISelectionFeedbackGeneratorAndroid: Uses VibrationEffect (API 26+) or Vibrator for older versionsWeb: Uses the Vibration API where supported
Best Practices
- Use Sparingly: Overuse can be annoying
- Match Interaction: Use appropriate feedback type for the interaction
- Respect Settings: Haptics honor system settings (vibration off, etc.)
- Light for UI: Use
Light impact for most UI interactions
- Notifications for States: Use notification feedback for success/error states
Resources