Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »


1.1.4 • Public • Published


npm package Follow on Twitter

pan-responder-hook offers a gesture responder system for your react application. It's heavily inspired by react-native's pan-responder and the implementation found in react-native-web. It's built for use in Sancho-UI.


  • The ability to delegate between multiple overlapping gestures. This means that you can embed gesture responding views within eachother and provide negotiation strategies between them.
  • Simple kinematics for gesture based animations. Values including distance, velocity, delta, and direction are provided through gesture callbacks.
  • Integrates well with react-spring to create performant animations.

Getting started

Install into your react project using yarn or npm.

yarn add pan-responder-hook

The example below demonstrates how it can be used in conjunction with react-spring.

import { useSpring, animated } from "react-spring";
import { usePanResponder } from "pan-responder-hook";
function Draggable() {
  const [{ xy }, set] = useSpring(() => ({
    xy: [0, 0]
  const { bind } = usePanResponder({
    onStartShouldSet: () => true,
    onRelease: onEnd,
    onTerminate: onEnd,
    onMove: state => {
        xy: delta,
        immediate: true
  function onEnd() {
    set({ xy: [0, 0], immediate: false });
  return (
        transform: xy.interpolate((x, y) => `translate3d(${x}px, ${y}px, 0)`)


Only one pan responder can be active at any given time. The pan-responder hook provides callbacks which allow you to implement a negotiation strategy between competing views.

  • onStartShouldSet: (state, e) => boolean - Should the view become the responder upon first touch?
  • onMoveShouldSet: (state, e) => boolean - This is called during any gesture movement on the view. You can return true to claim the responder for that view.
  • onStartShouldSetCapture: (state, e) => boolean - The same as above, but using event capturing instead of bubbling. Useful if you want a parent view to capture the responder prior to children.
  • onMoveShouldSetCapture: (state, e) => boolean.
  • onTerminationRequest: (state) => boolean. - Should we allow the responder to be claimed by another view? This is only called when a parent onMoveShouldSet returns true. By default, it returns true.

By default, if a parent and child both return true from onStartShouldSet the child element will claim the responder.

Once a responder is claimed, other callbacks can be used to provide visual feedback to the user.

  • onGrant: (state, e) => void - called when the view claims the responder, typically corresponding with mousedown or touchstart events.
  • onMove: (state, e) => void
  • onRelease: (state, e) => void - corresponds with mouseup or touchend events.
  • onTerminate: (state) => void - called when the responder is claimed by another view.
const { bind } = usePanResponder(
    onStartShouldSet: state => true,
    onStartShouldSetCapture: state => false,
    onMoveShouldSet: state => false,
    onMoveShouldSetCapture: state => false,
    onTerminationRequest: state => true,
    onGrant: state => {},
    onRelease: state => {},
    onTerminate: state => {},
    onMove: state => {}
    uid: "a-unique-id",
    enableMouse: true

state contains the following values:

export interface StateType {
  xy: [number, number];
  delta: [number, number];
  initial: [number, number];
  previous: [number, number];
  direction: [number, number];
  local: [number, number];
  lastLocal: [number, number];

Prior art


npm i pan-responder-hook

DownloadsWeekly Downloads






Unpacked Size

49.9 kB

Total Files


Last publish


  • avatar