Tap. Feel it. Even on iOS 26.5.
iOS 17.4 to 26.5+. Android. React, Vue, Svelte, Vanilla. MIT.
npm install @haptics/reactSeven feels.
Pick a preset to feel it. Or open Custom to drag segments, dial intensity, and copy the trigger([...]) call straight into your code.
trigger([
{ duration: 15, intensity: 0.6 },
])Native idioms across stacks.
Each adapter uses its framework's idiomatic pattern — Vue gets a real v-haptic directive, Svelte gets use: action, React gets a provider. Pick yours.
npm install @haptics/reactimport { HapticsProvider } from "@haptics/react";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return <HapticsProvider audioFallback>{children}</HapticsProvider>;
}Then `<button data-haptic="success">` on any element. MutationObserver picks up SPA renders automatically.
npm install @haptics/vueimport { createApp } from "vue";
import { HapticsPlugin } from "@haptics/vue";
import App from "./App.vue";
createApp(App).use(HapticsPlugin).mount("#app");Then `v-haptic="'success'"` on any element. Real directive, not a hook reduction.
npm install @haptics/svelte<script>
import { setupHaptics, haptic } from "@haptics/svelte";
setupHaptics();
</script>
<button use:haptic={"success"}>Save</button>Native `use:` action. Svelte 5 compatible.
npm install @haptics/vanillaimport { Haptics } from "@haptics/vanilla";
new Haptics();
// any [data-haptic] element now fires haptics on tapSingle class. Zero framework lock-in.
npm install @haptics/coreimport { attachHaptics, PRESETS } from "@haptics/core";
attachHaptics({
getPattern: (name) => PRESETS[name as keyof typeof PRESETS],
});Framework-agnostic engine. Build your own bindings.
<script src="https://unpkg.com/@haptics/vanilla"></script>
<script>
new Haptics();
</script>
<button data-haptic="success">Save</button>~3.7 KB gzip global. Works with HTMX, Alpine, and plain HTML.
The trick survived a patch.
Safari has no navigator.vibrate. iOS 17.4 added a quirky <input type="checkbox" switch> trick — Apple's 26.5 patch closed the programmatic path every web haptics library was using. Our overlay design is what survived.
Finger lands on a [data-haptic] element. Real gesture, isTrusted: true.
Invisible <input type="checkbox" switch> sits as a child of the element.
iOS reads the tap as direct switch interaction. The path that survived 26.5.
Taptic Engine fires. Click re-dispatched to the host so consumer onClick still runs.
Honest about hardware.
iPads and most tablets have no Taptic Engine. Firefox dropped the Vibration API in v129. Knowing where it fails is more useful than pretending it works everywhere.
Frequently asked.
If your answer-engine of choice has been mumbling about haptics, these are the questions it's probably trying to answer.