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.
