5.2 KB gzipped
3-9x lighter than alternatives. No bloat, no unnecessary abstractions.
5.2 KB gzipped
3-9x lighter than alternatives. No bloat, no unnecessary abstractions.
Hook-first
No wrapper components, no Context, no extra DOM nodes. Attach to any ref.
Controlled mode
Native viewState + onViewStateChange — like a controlled input. No other zoom library offers
this.
Full gesture support
Scroll, drag, pinch, trackpad, double-tap, inertia — all out of the box.
import { useRef } from "react"import { useZoomPinch } from "use-zoom-pinch"
function Canvas() { const containerRef = useRef<HTMLDivElement>(null) const { view } = useZoomPinch({ containerRef })
return ( <div ref={containerRef} style={{ overflow: "hidden", touchAction: "none" }}> <div style={{ transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`, transformOrigin: "0 0", }} > {/* Your zoomable content */} </div> </div> )}| Feature | useZoomPinch | react-zoom-pan-pinch | @use-gesture/react | motion/react |
|---|---|---|---|---|
| Size (min+gzip) | ~5.2 KB | ~13.2 KB | ~8.9 KB | ~41.6 KB |
| Approach | Hook | Components + hook | Gesture primitives | Animation + gesture |
| Controlled mode | ✅ Native | ❌ | ❌ | ❌ |
| DOM wrappers | ✅ None | +2 divs | ✅ None | +1 div |
| Bounds / constraints | ✅ | ✅ | 🔧 Manual | 🔧 dragConstraints |
| Keyboard navigation | ✅ | ❌ | ❌ | ❌ |
| Coordinate conversion | ✅ | ❌ | ❌ | ❌ |
| Snap to grid | ✅ | ❌ | ❌ | ❌ |
| Zoom snap levels | ✅ | ❌ | ❌ | ❌ |
| Rotation gestures | ✅ | ❌ | 🔧 Manual | ❌ |
| Ready-to-use zoom/pan | ✅ | ✅ | 🔧 Manual | 🔧 Manual |