Pragmatic drag and drop

A low-level, framework-agnostic drag and drop toolkit built on native browser DnD, powering Trello, Jira, and Confluence.

Library
npm
v4.0.0
12,787 stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
71 /100 Good
Development Activity 96
Maintenance 52
Community 48
Maturity 48
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
91 /100 Excellent
Architecture 88
Code Quality 90
Innovation 85
Learning Curve 100

Pragmatic drag and drop is Atlassian’s low-level toolchain for building drag and drop experiences on top of the browser’s native HTML5 drag and drop API, rather than replacing it with synthetic pointer-event simulation the way most drag and drop libraries do. The core package is deliberately tiny (around 4.7kB), headless, and framework agnostic — it ships adapters for element-to-element dragging, dragging files/text/links in from outside the browser, and dragging selected text, all coordinated through a shared internal lifecycle manager and usage ledger rather than three independent implementations.

The library is designed for incremental adoption: consumers import only the entry points they need (element/adapter, external/adapter, text-selection/adapter, plus optional utilities like reorder, combine, and prevent-unhandled), and each optional capability — auto-scrolling, visual drop indicators, screen-reader live-region messaging, hitbox-based interaction zones — ships as a separate, independently-versioned package so unused features never end up in a consumer’s bundle.

It currently powers drag and drop in Trello, Jira, and Confluence, which has pushed the project toward heavy attention to browser edge cases: iOS/Android native drag quirks, iframe boundaries, text-selection collisions, and recovery from interrupted or “broken” drags are all handled as first-class scenarios with dedicated tests, rather than being left as known limitations.

What You Get

  • A tiny (~4.7kB) core package providing draggable, dropTargetForElements, and monitorForElements primitives built directly on native HTML5 drag and drop events
  • Separate adapters for element-to-element drags, drags of files/links/text originating outside the browser (external/adapter), and drags of selected text (text-selection/adapter)
  • Optional, independently-installable packages for auto-scrolling during a drag, visual drop-indicator flourishes, hitbox-based edge/closest-edge detection, and screen-reader live-region announcements
  • Granular per-feature entry points (e.g. utils/reorder, utils/combine, utils/prevent-unhandled) so bundlers only include the code actually imported
  • Built-in handling for known native drag-and-drop browser quirks: the Chrome/Firefox honey-pot fix, iframe boundary crossing, Android/iOS native drag requirements, and recovery from drags interrupted mid-flight

Common Use Cases

  • Reordering items in a list or Kanban board (the pattern Trello and Jira use for card and column reordering)
  • Building a file-upload dropzone that accepts files dragged in from the user’s desktop via the external adapter
  • Adding drag-to-reorder or drag-to-move behavior to a custom design system without adopting a full DnD framework’s rendering opinions
  • Providing accessible, screen-reader-friendly drag and drop flows using the optional live-region package for assistive technology users
  • Cross-window or cross-application drag interactions, such as dragging a card out of one browser tab/app and having another page’s native adapter pick it up

Under The Hood

Architecture

The core package centers on a makeAdapter() factory (src/make-adapter/make-adapter.ts) that each concrete adapter (element, external, text-selection — see src/adapter/element-adapter.ts) configures with a mount() function and an event dispatcher; makeAdapter wires that into a shared singleton lifecycle-manager (src/ledger/lifecycle-manager.ts) and usage-ledger (src/ledger/usage-ledger.ts) so only one set of native dragstart/dragover/drop listeners is ever bound to document regardless of how many adapters or draggables are registered. The element adapter itself tracks registered draggable elements in a WeakMap-backed registry, listens for native dragstart on document, resolves the drag’s source/target through that registry, and hands off to the shared lifecycle to dispatch events to drop targets and monitors; because all three adapters funnel through this same lifecycle/ledger pair, a change to that core dispatch path is the single highest-blast-radius change in the codebase. Public entry points (src/entry-point/**) are thin, often-deprecated re-export shims pointing at the real implementation in src/adapter and src/public-utils, which lets the package restructure internals while keeping a stable public import surface.

Tech Stack

The package is TypeScript-only (96%+ of the repo by bytes) with a minimal runtime dependency footprint — just @babel/runtime, bind-event-listener for declarative native event binding, and raf-schd for rAF-scheduled callbacks (used by the auto-scroll package). It’s built and published from an internal Atlassian monorepo mirrored here via Yarn workspaces (packages/*), compiled to CJS, ESM, and an es2019 target with separate .d.ts type output, and has zero required peer dependencies on React or any view framework — React only appears as a devDependency for testing and in the optional react-drop-indicator/react-accessibility packages.

Code Quality

The repo has an unusually large test surface for its size — over 100 spec files under __tests__/unit and __tests__/playwright, including dedicated regression tests for cross-browser drag edge cases (honey-pot.spec.ts, iframe.spec.ts, text-selection.spec.ts, dropping-outside-window.spec.ts, error-recovery.spec.ts). TypeScript is run in strict mode with noUnusedLocals and isolatedModules enabled, and the codebase makes heavy, explicit use of inline JSDoc comments documenting why a given browser workaround exists (citing specific Chrome/Firefox/Safari/Android version testing), which is atypical thoroughness for a low-level UI library. No CI workflow files ship in this mirror repository, since it is explicitly a one-way sync from Atlassian’s internal monorepo rather than the place PRs are built and merged.

What Makes It Unique

Most drag and drop libraries (react-dnd, dnd-kit, SortableJS-style tools) simulate dragging entirely with pointer/mouse events to sidestep the browser’s native, notoriously inconsistent HTML5 drag and drop API. Pragmatic drag and drop instead builds directly on top of that native API, which is a harder engineering problem (native DnD has real cross-browser and cross-platform quirks) but buys back capabilities synthetic implementations give up for free: native OS-level drag previews, dragging files in from the desktop, and dragging content out to other browser windows or applications. Combined with its adapter/entry-point splitting, this makes it closer to a drag and drop substrate other design systems build on top of than a ready-made drag and drop UI component.

Used by 35 apps in this directory

TypeScript
67%
AGPL 3.0

Plane

Collaboration · Productivity · Project Management

61,353

Open-source project management platform to replace Jira, Linear, and ClickUp — with built-in cycles, real-time collaborative docs, and full self-hosting.

View details
92
Repo Health
82
Technical
77
Dependency
Built with
TypeScript 67%
Python 30%
Updated 1 weeks ago
TypeScript
67%
AGPL 3.0

Plane

Collaboration · Productivity · Project Management

61,353

Open-source project management platform to replace Jira, Linear, and ClickUp — with built-in cycles, real-time collaborative docs, and full self-hosting.

View details
92
Repo Health
82
Technical
77
Dependency
Built with
TypeScript 67%
Python 30%
Updated 1 weeks ago
TypeScript
67%
AGPL 3.0

Plane

Collaboration · Productivity · Project Management

61,353

Open-source project management platform to replace Jira, Linear, and ClickUp — with built-in cycles, real-time collaborative docs, and full self-hosting.

View details
92
Repo Health
82
Technical
77
Dependency
Built with
TypeScript 67%
Python 30%
Updated 1 weeks ago
TypeScript
47%
Other

Stirling PDF

Digital Signiture · Productivity

94,824

The open-source PDF platform you can run anywhere — edit, convert, sign, and automate PDFs without sending files to external servers.

View details
92
Repo Health
86
Technical
68
Dependency
Built with
TypeScript 47%
Java 44%
Updated 6 days ago
TypeScript
63%
AGPL 3.0

undb

Databases · No Code Platforms

2,975

Self-hosted no-code database and BaaS that lets you manage structured data visually with multi-database support, formula fields, and auto-generated OpenAPI endpoints.

View details
58
Repo Health
66
Technical
65
Dependency
Built with
TypeScript 63%
Svelte 35%
Updated 1 months ago
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

9,103

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

9,103

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

9,103

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago

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