Flutter package
haptic_kit
Haptic feedback, vibration and animated widgets for Flutter — the right haptic at the right moment.
haptic_kit
Semantic haptics, longer vibrations and capability detection — plus the quickstart that makes your UI feel native.
source: README.mdhaptic_kit
The right haptic at the right moment
Haptic feedback, vibration and animated UI widgets for Flutter — full Android & iOS implementations covering everything from quick UI taps to custom Core Haptics patterns with intensity and sharpness curves, plus a set of production-ready widgets wired to the right haptic at the right moment. Zero runtime dependencies beyond the Flutter SDK.
| API | What it gives you |
|---|---|
Haptics | Short, semantic taps (named Haptics to avoid clashing with Flutter's own HapticFeedback): impact light / medium / heavy / soft / rigid, notification success / warning / error, selection, and prepare() to pre-warm generators on iOS. |
Vibration | One-shot with optional amplitude, custom waveforms with per-segment amplitudes, predefined OS effects (tick, click, doubleClick, heavyClick) and cancel. |
HapticPattern | Fluent builder for Core Haptics patterns: transient taps + continuous events, per-event intensity and sharpness (0.0–1.0), automatically translated to Android amplitude waveforms. |
VibrationPatterns | Ready-made presets: heartbeat, notification, alarm, tick, success, failure, charge-up and doubleTap. |
HapticCapabilities | Runtime detection of vibrator hardware, amplitude control, Core Haptics and predefined effects. |
| 9 animated widgets | HapticBounce, PressAndHoldToConfirm, HapticToggle, HapticSlider, HapticStepper, HapticShake, SlideToConfirm and HapticRating — each pairs its animation with the correct haptic. |
Platform support
| Feature | Android | iOS |
|---|---|---|
| Impact / notification / selection | ✅ API 21+ (best on 26+) | ✅ iOS 10+ |
| One-shot + amplitude | ✅ API 26+ | ✅ iPhone 8+ (Core Haptics) |
| Custom waveforms | ✅ API 26+ | ✅ iPhone 8+ |
| Predefined effects | ✅ API 29+ | ↩︎ mapped to closest impact |
| Custom patterns (intensity + sharpness) | ✅ API 26+ | ✅ iPhone 8+ |
| Capability detection | ✅ | ✅ |
Setup
Install & platform setup
Add haptic_kit to your pubspec.yaml. Import everything through the single entry point package:haptic_kit/haptic_kit.dart.
dependencies:
haptic_kit: ^2.0.0Environment
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"Android
The plugin's AndroidManifest.xml already declares VIBRATE — nothing else to do.
<uses-permission android:name="android.permission.VIBRATE" />iOS
CoreHaptics, UIKit and AudioToolbox are linked automatically through the podspec. Flutter 3.44+ projects can also resolve the plugin via Swift Package Manager; CocoaPods continues to work unchanged.
Breaking change in 2.0.0 — iOS 15.0
The minimum iOS deployment target was raised from 12.0 to 15.0. Apps targeting iOS 12–14 must either stay on 1.x or raise their own deployment target. Set your app's IPHONEOS_DEPLOYMENT_TARGET (and the Podfile platform) to 15.0 or higher before upgrading. The runtime APIs are still guarded for iOS 13.0+ (Core Haptics), but the SPM tooling and example require 15.0.
First taps
Quickstart
Every call is a static Future you can await in a UI callback. Semantic taps, longer vibrations, custom waveforms, predefined OS effects and ready-made patterns all live behind these entry points.
import 'package:haptic_kit/haptic_kit.dart';
// Short UI taps
await Haptics.impact(HapticImpactStyle.medium);
await Haptics.notification(HapticNotificationStyle.success);
await Haptics.selection();
// Longer vibrations
await Vibration.vibrate(duration: const Duration(milliseconds: 300));
// Custom waveform — three pulses with growing amplitude
await Vibration.vibrateWaveform(
timings: const [
Duration.zero,
Duration(milliseconds: 100),
Duration(milliseconds: 100),
Duration(milliseconds: 100),
Duration(milliseconds: 100),
Duration(milliseconds: 100),
],
amplitudes: const [0, 80, 0, 160, 0, 255],
);
// Predefined OS effect
await Vibration.playPredefined(PredefinedEffect.doubleClick);
// Ready-made pattern
await VibrationPatterns.heartbeat();Guidance
Choosing the right haptic
The trick is matching the moment to the feedback — quiet for repeated steps, weightier as the interaction closes. Reach for these defaults:
| Moment | Haptic | Why |
|---|---|---|
| Crossing a discrete step (slider, picker, page) | Haptics.selection() | Quietest tap — never fatiguing. |
| Press-down on a button | Haptics.impact(light) | Subtle 'I felt your touch'. |
| Release / tap completes | Haptics.impact(medium) | The 'click'. |
| Long-press completes / drag confirms | Haptics.impact(heavy) | Closes the loop with weight. |
| Validation passed | Haptics.notification(success) | Two-tap pattern, recognisable. |
| Soft error / boundary hit | Haptics.notification(warning) | Three-tap warning pattern. |
| Hard error / wrong input | Haptics.notification(error) | Sharp triple-tap. |
| Custom intensity + sharpness curve | HapticPattern.builder()…play() | Core Haptics on iOS, amplitude on Android. |
Detection
Detect capabilities first
Not every device renders every effect. Call HapticCapabilities.query() once on app start (or on the first user interaction) and cache the result — the values do not change at runtime. Then degrade gracefully: fall back from a rich pattern to a plain notification when custom patterns are unavailable.
final caps = await HapticCapabilities.query();
if (caps.supportsCustomPatterns) {
await VibrationPatterns.success();
} else {
await Haptics.notification(HapticNotificationStyle.success);
}The full capability field set — hasVibrator, hasAmplitudeControl, supportsCustomPatterns, supportsPredefinedEffects and supportsImpactFeedback — plus the typed error hierarchy is documented on the Patterns & API page.
Keep going
Where to go next
Let's make something together.
If you have any questions about a new project or other inquiries, feel free to contact us. We will get back to you as soon as possible.
