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

Rust
68%
Other

GitButler

AI Development · Developer Tools · Devops

21,841

Git, but better — a modern version control client with stacked branches, parallel workflows, unlimited undo, and first-class support for AI-powered development.

View details
89
Repo Health
84
Technical
66
Dependency
Built with
Rust 68%
TypeScript 20%
Updated 6 days ago
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,338

Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.

View details
98
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,338

Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.

View details
98
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
98%
Other

LobeHub

AI Assistants · Automation · Productivity

83,455

Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
98%
Other

LobeHub

AI Assistants · Automation · Productivity

83,455

Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
51%
Other

Mattermost

Collaboration · Devops · Team Chat

39,418

Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.

View details
96
Repo Health
87
Technical
65
Dependency
Built with
TypeScript 51%
Go 40%
Updated 6 days ago
TypeScript
51%
Other

Mattermost

Collaboration · Devops · Team Chat

39,418

Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.

View details
96
Repo Health
87
Technical
65
Dependency
Built with
TypeScript 51%
Go 40%
Updated 6 days ago
TypeScript
51%
Other

Mattermost

Collaboration · Devops · Team Chat

39,418

Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.

View details
96
Repo Health
87
Technical
65
Dependency
Built with
TypeScript 51%
Go 40%
Updated 6 days ago
TypeScript
97%
MIT

NewsNow

Bookmarks Archiving

22,143

Self-hostable news aggregator with an elegant column layout, GitHub OAuth, adaptive scraping intervals, and seamless Cloudflare D1 or SQLite persistence.

View details
75
Repo Health
74
Technical
70
Dependency
Built with
TypeScript 97%
Updated 2 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