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
v3.1.0
12,750stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity96
Maintenance52
Community48
Maturity48
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
91/100Excellent
Architecture88
Code Quality90
Innovation85
Learning Curve100

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
87%
Other

AFFiNE

Productivity · Project Management · Note Taking

72,238

Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.

View details
91
Repo Health
87
Technical
67
Dependency
Built with
TypeScript87%
Updated yesterday
TypeScript
87%
Other

AFFiNE

Productivity · Project Management · Note Taking

72,238

Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.

View details
91
Repo Health
87
Technical
67
Dependency
Built with
TypeScript87%
Updated yesterday
TypeScript
87%
Other

AFFiNE

Productivity · Project Management · Note Taking

72,238

Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.

View details
91
Repo Health
87
Technical
67
Dependency
Built with
TypeScript87%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
Rust
67%
Other

GitButler

Developer Tools · Devops · AI Development

21,624

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
67
Dependency
Built with
Rust67%
TypeScript20%
Svelte11%
Updated yesterday

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