Pragmatic drag and drop
A low-level, framework-agnostic drag and drop toolkit built on native browser DnD, powering Trello, Jira, and Confluence.
Repository Health
Technical Analysis
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, andmonitorForElementsprimitives 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
AFFiNE
Productivity · Project Management · Note Taking
Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.
AFFiNE
Productivity · Project Management · Note Taking
Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.
AFFiNE
Productivity · Project Management · Note Taking
Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.
Docmost
Productivity · Note Taking · Collaboration
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.
Docmost
Productivity · Note Taking · Collaboration
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.
Docmost
Productivity · Note Taking · Collaboration
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.
Docmost
Productivity · Note Taking · Collaboration
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.
Docmost
Productivity · Note Taking · Collaboration
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.
GitButler
Developer Tools · Devops · AI Development
Git, but better — a modern version control client with stacked branches, parallel workflows, unlimited undo, and first-class support for AI-powered development.