---
title: "Haptics"
description: "Haptic feedback mapped per platform: iOS, Android, watchOS, and web vibration patterns for the shared event vocabulary."
url: https://buenalabs.io/design/haptics
---

# Haptics

The same event vocabulary as Sound (https://buenalabs.io/design/sound.md), expressed as touch. Each event maps to the platform's native generator — never hand-rolled vibration where semantic APIs exist.

## Platform mapping

| Event | iOS | Android | watchOS | Web (navigator.vibrate) |
|-------|-----|---------|---------|-------------------------|
| tap | UISelectionFeedbackGenerator | EFFECT_TICK | .click | [10] |
| click | UIImpactFeedbackGenerator(.light) | EFFECT_CLICK | .click | [18] |
| open | UIImpactFeedbackGenerator(.medium) | EFFECT_HEAVY_CLICK | .start | [12, 40, 24] |
| close | UIImpactFeedbackGenerator(.light) | EFFECT_CLICK | .stop | [24, 40, 12] |
| success | UINotificationFeedbackGenerator(.success) | EFFECT_DOUBLE_CLICK | .success | [12, 60, 24] |
| warning | UINotificationFeedbackGenerator(.warning) | EFFECT_HEAVY_CLICK | .retry | [30, 40, 30] |
| error | UINotificationFeedbackGenerator(.error) | waveform [50, 60, 50] | .failure | [50, 60, 50] |

Android values are VibrationEffect predefined constants. Web patterns are vibrate/pause milliseconds; unsupported on iOS Safari — fail silently.

## Rules

- Haptics accompany visual feedback, never replace it.
- Use the platform's semantic generator, not raw vibration, wherever one exists.
- Fire the haptic with its matching sound when both are on; one event, one moment.
- Honor reduced-motion and system haptic settings; expose one in-app toggle.
- Rarity is the point: reserve success/warning/error for moments that matter.