Every gesture library hooks into DOM events. Hammer.js (deprecated). use-gesture (React-only). interact.js (DOM-dependent).
But a gesture is just math.
A swipe is fast displacement along one axis. A tap is low drift over short time. A flick is high velocity over minimal distance. None of this requires a browser.
Introducing @aumiqx/gesture
Pure-math gesture recognition for JavaScript. ~6KB. Zero dependencies. Works in React, Node.js, Canvas, WebGL, Deno, Bun, or a server analyzing session replays.
import { recognize } from "@aumiqx/gesture"
const gesture = recognize([
{ x: 100, y: 200, t: 0 },
{ x: 300, y: 195, t: 32 },
{ x: 450, y: 201, t: 64 },
])
// {
// type: "swipe",
// direction: "right",
// velocity: 5.47,
// confidence: 0.92,
// distance: 300,
// curvature: 0.01,
// predictedEnd: { x: 520, y: 203 }
// }
Input coordinates. Get classification. That's it.
The Problem We Solved
Every existing gesture library is event-driven. They attach to the DOM, listen for pointer events, maintain internal state machines, and fire callbacks. This creates three fundamental limitations:
- DOM dependency — Can't use them on Canvas, WebGL, or server-side
- Framework lock-in — use-gesture is React-only, Hammer.js is vanilla-only
- No retroactive analysis — Can't classify gestures from logged data after the fact
Our library flips the model. A gesture is a mathematical pattern in a sequence of (x, y, timestamp) coordinates. The classification is pure computation:
- Straight-line distance between first and last point
- Path curvature — total path length divided by straight distance
- Velocity — distance over time
- Max drift from centroid — measures how stationary the touch was
- Duration — total time elapsed
These five numbers determine every gesture type. No events needed.
What It Detects
| Type | Detection Logic | Use Case |
|---|---|---|
| tap | duration < 300ms, drift < 10px | Button clicks, selection |
| long-press | duration > 500ms, drift < 15px | Context menus, drag mode |
| swipe | distance > 30px, velocity > 0.3 px/ms | Navigation, card dismissal |
| flick | velocity > 1.5 px/ms, duration < 200ms | List scrolling, page turning |
| pan | slow movement, exceeds tap threshold | Map dragging, object moving |
Each result includes a confidence score (0-1), direction (up/down/left/right), and a predicted endpoint — where the gesture would land if it continued with friction decay.
Mid-Gesture Prediction
This is the feature that changes how you build UIs:
import { predict } from "@aumiqx/gesture"
// Call WHILE the user is still moving
const { likely, alternatives } = predict(partialPoints)
// likely.type = "swipe" (78% confidence)
// Start the transition NOW, before they finish
Your UI reacts to gestures before they complete. The difference between "responsive" and "telepathic."
How It Compares
| Feature | Hammer.js | use-gesture | @aumiqx/gesture |
|---|---|---|---|
| DOM required | Yes | Yes | No |
| Framework | None | React only | Any / none |
| Server-side | No | No | Yes |
| Canvas/WebGL | No | No | Yes |
| Mid-gesture prediction | No | No | Yes |
| Bundle size | 7.3KB | 12KB | ~6KB |
| Maintained | Deprecated | Yes | Yes |
| Dependencies | 0 | 0 | 0 |
Real-World Use Cases
Canvas/WebGL Games — Gesture controls without DOM elements. Detect swipes, flicks, and holds directly from pointer data in your render loop.
Session Replay Analytics — Classify user gestures from logged pointer data on a server. Find rage-clicks, hesitant scrolls, and confused navigation patterns. Run in Node.js, not a browser.
Gesture Prediction — Call predict() mid-gesture to start UI responses before the gesture completes. Snappy interfaces that feel like they read your mind.
Accessibility — Classify shaky or imprecise input from users with motor impairments. Distinguish intentional gestures from tremor-induced movement by adjusting thresholds.
Custom Gesture Vocabularies — Combine recognized gestures into compound patterns. Swipe-then-hold = drag mode. Double-tap-then-swipe = selection gesture.
The Math Under the Hood
Every function is exported so you can build custom recognizers:
import {
distance, // Euclidean between two points
straightLineDistance, // First to last point
totalPathLength, // Sum of all segments
velocity, // distance / time
curvature, // path / straight - 1 (0 = perfectly straight)
maxDrift, // max distance from centroid
centroid, // average position of all points
angle, // atan2 direction in radians
predictEnd, // extrapolate from velocity + friction
} from "@aumiqx/gesture"
The entire library is trigonometry, linear regression, and threshold matching. No ML. No neural networks. No WASM. Just math.
Try It Live
We built an interactive demo with 12 gesture presets — tap, swipe (4 directions), flick, long-press, pan, circle, zigzag, diagonal, and unknown.
Click any preset to see the engine classify it step-by-step. Or draw your own gesture on the canvas and watch real-time prediction as you move.
Install
npm install @aumiqx/gesture
# or
pnpm add @aumiqx/gesture
MIT licensed. TypeScript. Zero dependencies. ~6KB.
Built by Aumiqx — we build AI agents, workflow automations, and open-source tools that shouldn't work but do.
Top comments (0)