npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flare-engine/haptics

v0.4.8

Published

Haptics (tactile feedback) provider interface (consumer-supplied adapter)

Readme

@flare-engine/haptics

Typed HapticsProvider interface, a React context, and concrete providers you wire at the app boundary via injection — no expo-haptics or react-native dependency. Ships an Expo Haptics adapter, a Web Vibration adapter, and no-op fallbacks.

Install

bun add @flare-engine/haptics

Usage

Pick a provider at the app boundary and put it on the context. The cue surface is three semantic calls — impact(style?) for weapon / hit / bomb feel, notification(type?) for victory / error cues, and selection() for light UI ticks — plus an isEnabled() / setEnabled(enabled) gate. The gate keeps the user's haptics setting and the reduced-motion gate (@flare-engine/a11y) in one place; when disabled, cue methods are no-ops.

import * as Haptics from 'expo-haptics';
import {
  createExpoHapticsProvider,
  createWebVibrationProvider,
  HapticsContext,
} from '@flare-engine/haptics';

// Native: inject the expo-haptics module. Web: inject navigator.vibrate.
// Neither is a dependency of this package — the platform module is passed in.
const provider =
  typeof navigator !== 'undefined' && 'vibrate' in navigator
    ? createWebVibrationProvider(navigator.vibrate.bind(navigator))
    : createExpoHapticsProvider(Haptics);

export function App() {
  return (
    <HapticsContext.Provider value={provider}>
      {/* ... */}
    </HapticsContext.Provider>
  );
}
import { Button } from 'react-native';
import { useHaptics } from '@flare-engine/haptics';

function FireButton() {
  const haptics = useHaptics();
  return <Button title="Fire" onPress={() => haptics.impact('heavy')} />;
}

HapticsContext defaults to NoopHapticsProvider, so useHaptics() is always safe to call. createWebVibrationProvider(undefined) (no Vibration API) returns that same inert no-op, so web code needs no feature-detect.

Providers

| Factory | Backend | Notes | | --- | --- | --- | | createExpoHapticsProvider(expo) | expo-haptics (injected) | expo is the structural { impactAsync, notificationAsync, selectionAsync } shape; cue kinds map onto expo's string enums 1:1. Starts enabled. | | createWebVibrationProvider(vibrate?) | Web Vibration API | vibrate is navigator.vibrate bound to navigator. Impact scales the buzz with intensity; each notification category has its own pulse pattern; selection is a short tick. Absent vibrate → inert no-op. | | NoopHapticsProvider | none | Immutable, always disabled — the context default and the safe fallback. setEnabled is inert by design. | | createNoopHapticsProvider(enabled?) | none | No-op cues but a real enabled gate, so a consumer's haptics toggle is unit-testable without a native backend. Defaults to disabled. |

Other backends

Any SDK works through injection — the same pattern the Expo and Web providers use. Wrap its calls in the impact / notification / selection shape and hand them to the shared gate, so your adapter never re-implements the enabled logic. For a native Vibration (from react-native) or a Core Haptics bridge, mirror createExpoHapticsProvider: accept the module, forward the cues, start enabled.