New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@amrshbib/react-native-haptic-feedback

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@amrshbib/react-native-haptic-feedback

Semantic haptics for React Native. Real Taptic Engine on iOS (selection, impact, notification) and Core Haptics for arbitrary durations; VibrationEffect primitives on Android. One vocabulary, no dead 400ms buzz.

latest
Source
npmnpm
Version
0.0.1
Version published
Weekly downloads
6
100%
Maintainers
1
Weekly downloads
 
Created
Source

@amrshbib/react-native-haptic-feedback

Semantic haptics for React Native. Nine named events — the ones Apple designed — routed to the real Taptic Engine on iOS and to VibrationEffect primitives on Android, plus Core Haptics for anything with a duration.

React Native ships Vibration, and on iOS it plays exactly one thing: the 400 ms slab an incoming call uses. It ignores durations, ignores patterns, and is far too heavy to put behind a button. That is why most apps end up with Platform.OS === "android" && Vibration.vibrate(20) and no haptics at all on the platform that has the best ones. This is the fix.

Install

npm install @amrshbib/react-native-haptic-feedback
cd ios && pod install

Autolinked on both platforms. Android's VIBRATE permission is merged in from the library manifest — there is nothing to add to the app. Rebuild after installing; restarting Metro is not enough.

Use

import Haptics, { HAPTIC } from "@amrshbib/react-native-haptic-feedback";

Haptics.selection();          // a value changed under the finger
Haptics.light();              // a tap that did something
Haptics.success();            // it worked
Haptics.trigger(HAPTIC.ERROR);

The nine

NameMeansiOSAndroid (API 30+)
selectiona value changed under the finger — a tab, a chip, a stepperUISelectionFeedbackGeneratorPRIMITIVE_TICK @ 0.45
impactLightsomething small landedimpact, lightPRIMITIVE_CLICK @ 0.5
impactMediumsomething landedimpact, mediumPRIMITIVE_CLICK @ 0.75
impactHeavysomething heavy landedimpact, heavyPRIMITIVE_CLICK @ 1.0
impactSofta dull edgeimpact, softPRIMITIVE_TICK @ 1.0
impactRigida hard edgeimpact, rigidPRIMITIVE_CLICK @ 1.0
notificationSuccessit workednotification, successtwo clicks, 90 ms apart
notificationWarningread thisnotification, warningclick then tick
notificationErrorit did not worknotification, errorthree clicks

Android falls back a rung at a time — API 30 primitives, then API 29 predefined effects, then an API 26 waveform with amplitudes, then a bare duration. A caller asking for selection on a 2017 handset still gets the shortest thing that phone can do.

Durations

Haptics.vibrate(30);                 // 30 ms, honoured on both platforms
Haptics.pattern([0, 40, 80, 40]);    // wait, buzz, wait, buzz
Haptics.cancel();

pattern takes the same shape as React Native's own Vibration.vibrate on Android, so patterns written for it port across — and now run on iOS too, through Core Haptics.

Waiting

const stop = Haptics.pulse({ interval: 900 });
// …
stop();

A tick every interval until you stop it — for the thing a spinner cannot say, when the phone is face-down or the eyes are elsewhere. It stops itself after limit ticks (default 30) so a request that never returns cannot leave a phone buzzing in a pocket.

The switch

Haptics.setEnabled(false);  // one gate, held in JS, no bridge crossing to say no

Wire it to wherever the app keeps the user's answer. Held in JS on purpose: a gate that had to cross the bridge to decline would cost a round trip per tap to do nothing.

Handlers

<Button onPress={Haptics.haptic(handleSave, HAPTIC.SUCCESS)} />

The tick fires before the handler — the touch is what is being answered, not the result of it.

What the device can do

const { supported, engine, systemEnabled } = await Haptics.getCapabilities();

engine is "core-haptics", "vibrator", or "none" — the last meaning no motor at all, which is most simulators and every iPad. systemEnabled reflects Android's touch-feedback setting; iOS has no public read for System Haptics and always reports true, so do not branch on it — the platform enforces its own setting below this library either way.

Also

  • prepare() — both platforms power the motor down between uses, and the first tick after idle lands late enough to feel detached from the touch. Call it when a screen that will tick opens; not per tap, which is the same latency moved.
  • Repeats are collapsed. Two ticks of the same kind inside 24 ms are one tick — well under a deliberate double-tap, and enough to keep a fast-scrolling list from returning a smear.
  • A missing native module never throws. A build that has not been recompiled, a simulator, a web target: every call goes quiet, with one dev-mode warning. Haptics are decoration, and decoration must not be able to take a screen down.
  • Android honours the system touch-feedback setting for the nine named events, and not for vibrate/pattern — turning touch feedback off is a statement about taps, not about the buzz that says a voice recording has started.

Requirements

React Native ≥ 0.71 · iOS 13 · Android API 24

License

MIT © Amr Shbib

Keywords

react-native

FAQs

Package last updated on 12 Sep 2026

Related posts