react-native-haptic-library
v0.1.1
Published
Android-first React Native haptics library with TurboModules and JSI support.
Maintainers
Readme
react-native-haptic-library
Android-first React Native haptics library built for the New Architecture.
It provides:
- synchronous JSI-triggered haptics
- semantic haptic APIs for native-feel interactions
- custom one-shot and waveform vibration fallbacks
- capability inspection so apps can adapt to weaker hardware without depending on Android internals
Platform Support
- Android: supported
- iOS: not supported in this package version
Requirements
- React Native
>= 0.75.0 - Android New Architecture enabled
- A real Android device is recommended for testing haptics quality
Installation
npm install react-native-haptic-libraryFor local development in this repo:
npm install
npm run buildAndroid Setup
Enable the New Architecture in your app:
# android/gradle.properties
newArchEnabled=trueThe library declares VIBRATE in its Android manifest. No extra app-side permission wiring is typically needed.
Quick Start
import {
configure,
getCapabilities,
impact,
notification,
selection,
} from 'react-native-haptic-library';
configure({ ignoreSystemHapticSetting: false });
const capabilities = getCapabilities();
if (capabilities.isSupported) {
selection();
impact('medium');
notification('success');
}Public API
Setup
install(): boolean
Installs the JSI bindings explicitly.
This is optional. The library will lazily install its bindings on first haptic trigger. Call install() during app startup only if you want an explicit readiness check.
import { install } from 'react-native-haptic-library';
install();configure(settings?: { ignoreSystemHapticSetting?: boolean }): void
Configures view-haptics behavior.
- default: respects system and view haptic settings
- opt-in override:
ignoreSystemHapticSetting: true
configure({ ignoreSystemHapticSetting: true });cleanup(): void
Clears this library's installed bindings and native cached state.
import { cleanup } from 'react-native-haptic-library';
cleanup();Semantic Haptics
selection(): boolean
Triggers a fine selection-style tick.
selection();impact(style?: 'light' | 'medium' | 'heavy'): boolean
Triggers an impact-style haptic.
impact();
impact('light');
impact('heavy');notification(type: 'success' | 'warning' | 'error'): boolean
Triggers a notification-style haptic.
notification('success');
notification('warning');
notification('error');Custom Vibration
vibrate(options: { duration: number; amplitude?: number }): boolean
Triggers a one-shot vibration fallback.
duration: required, milliseconds,> 0amplitude: optional,-1or1..255
vibrate({ duration: 12 });
vibrate({ duration: 16, amplitude: 180 });waveform(options: { timings: number[]; amplitudes?: number[]; repeat?: number }): boolean
Triggers a waveform vibration fallback.
timings: required non-empty array of millisecondsamplitudes: optional, must matchtimings.lengthrepeat: optional,-1or a valid timings index
waveform({
timings: [0, 20, 16, 24],
amplitudes: [0, 180, 0, 220],
repeat: -1,
});Capability APIs
isAvailable(): boolean
Returns the native module availability state.
isSupported(): boolean
Returns whether the device has a usable haptics path.
getQualityTier(): 'premium' | 'standard' | 'basic' | 'unsupported'
Returns a simplified quality tier for product decisions.
getCapabilities(): HapticsCapabilities
Returns the full capability snapshot:
type HapticsCapabilities = {
isSupported: boolean;
hasVibrator: boolean;
hasAmplitudeControl: boolean;
hasVibratePermission: boolean;
canUseCustomVibration: boolean;
apiLevel: number;
qualityTier: 'premium' | 'standard' | 'basic' | 'unsupported';
};supportsAmplitudeControl(): boolean
Returns whether the device supports custom vibration amplitudes.
hasVibratePermission(): boolean
Returns whether vibration permission is available to the app process.
Quality Tier Guide
premium
Use full semantic haptics confidently. This usually means view haptics plus advanced Android primitives or predefined effects are available.
standard
Semantic haptics are available, but the device may not support the highest-fidelity path.
basic
Only generic vibration fallback is reliable. Use fewer haptics and prefer subtle feedback.
unsupported
Do not rely on haptics.
Usage Patterns
1. App Startup
import { install } from 'react-native-haptic-library';
install();2. Feature-Gated Semantic Haptics
import { getCapabilities, impact, selection } from 'react-native-haptic-library';
const capabilities = getCapabilities();
if (capabilities.isSupported) {
selection();
impact('medium');
}3. Quality-Based Product Behavior
import { getQualityTier, impact, selection } from 'react-native-haptic-library';
const qualityTier = getQualityTier();
if (qualityTier === 'premium' || qualityTier === 'standard') {
selection();
} else if (qualityTier === 'basic') {
impact('light');
}4. Custom Fallback Vibration
import { vibrate, waveform } from 'react-native-haptic-library';
vibrate({ duration: 10, amplitude: 140 });
waveform({
timings: [0, 12, 16, 18],
amplitudes: [0, 150, 0, 200],
repeat: -1,
});Behavior on Lower-End Devices
The library degrades by capability:
- advanced semantic haptics on stronger devices
- predefined or one-shot vibration on weaker devices
falsereturn values instead of crashes on unsupported hardware
This means lower-end devices may feel more like a buzz than a sharp native tick. That is expected and hardware-dependent.
Notes
- The JSI runtime state is internal to the library and is not part of the supported public API.
- The library prefers view haptics, predefined effects, and composition primitives before falling back to raw
VibrationEffect. - For the best experience, test on real devices, not emulators.
