moveable

A JavaScript/TypeScript library that makes DOM elements draggable, resizable, scalable, rotatable, warpable, pinchable, and snappable

Library
npm
v0.53.0
10,749stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
53/100Fair
Development Activity0
Maintenance48
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
72/100Good
Architecture74
Code Quality70
Innovation78
Learning Curve66

Moveable is a manager-class-based UI manipulation library: point it at a DOM target and it adds interactive handles for dragging, resizing, scaling, rotating, warping (perspective transforms), pinch-zooming, grouping multiple targets, and snapping to guides or other elements. Rather than shipping separate libraries for each interaction, Moveable exposes each capability as an able (Draggable, Resizable, Scalable, …) that can be toggled on or off per instance.

The core moveable package is framework-agnostic vanilla JS/TypeScript, and the same monorepo publishes framework-specific wrappers — react-moveable, vue3-moveable (and Preact/Angular/Svelte variants) — built on top of it, so teams get idiomatic bindings for React or Vue without losing access to the underlying feature set.

What You Get

  • A single Moveable class that adds drag/resize/scale/rotate/warp/pinch handles to any DOM element via CSS transforms
  • Snapping support against guidelines, element edges, and other Moveable targets for precise alignment
  • Group mode for manipulating multiple selected targets together as one unit
  • Framework wrapper packages in the same monorepo (react-moveable, vue3-moveable, and others) exposing the same functionality as idiomatic components
  • An extensible ‘ables’ system (Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable, Snappable, Roundable, Clippable) that can be mixed per instance

Common Use Cases

  • Building drag-and-drop page builders, design tools, or WYSIWYG editors where users move/resize/rotate elements on a canvas
  • Adding interactive resize/rotate handles to image croppers or layout editors
  • Implementing draggable, snappable dashboard widgets or freeform layout systems
  • Multi-select group manipulation UIs (moving/scaling several elements together) in canvas-style editors

Under The Hood

Architecture: The core class lives in packages/moveable/src/Moveable.tsx and MoveableManager.tsx, which render an InnerMoveable component (InnerMoveable.tsx) responsible for drawing control handles and dispatching pointer events. Each interactive capability (‘able’) is implemented as a plugin-like module that Moveable composes at runtime based on which options (draggable, resizable, rotatable, etc.) are passed in, letting the manager stay agnostic to which specific gestures are active for a given instance. Framework wrappers (packages/react-moveable, packages/vue3-moveable, etc.) are thin adapters in the same monorepo that wrap the vanilla-JS Moveable class in framework-idiomatic components/composables.

Tech Stack: TypeScript (compiled via tsc for declarations, bundled with Rollup per the build/declaration npm scripts), published as both CJS and ESM builds (dist/moveable.cjs.js / dist/moveable.esm.js). The monorepo also ships a Storybook-based demo/docs site and uses jsdoc for API documentation generation, plus an internal print-sizes tool to track bundle size across releases.

Code Quality: The package.json build pipeline includes an e2e workflow (run-e2e.yml GitHub Action referenced in the README badges) alongside the declaration/build scripts, suggesting cross-browser interaction testing given how gesture-heavy this library’s surface is. With 38 contributors and ~1,612 commits across a project active since 2019, it has a long-lived, single-primary-maintainer development pattern (the daybrush author holds the large majority of contributions).

API Design: Instantiating new Moveable(el, { draggable: true, resizable: true, ... }) and listening for onDrag/onResize callback events is the primary interaction pattern — enabling a new capability is a one-line options change rather than composing separate libraries. The React/Vue wrapper packages mirror this same options shape as component props, keeping the mental model consistent whether used as vanilla JS or through a framework binding.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search