Skip to main content

dnd-kit vs react-beautiful-dnd vs Pragmatic DnD

·PkgPulse Team
0

TL;DR

react-beautiful-dnd is deprecated — Atlassian moved on and so should you. In 2026, @dnd-kit is the default choice for most React drag-and-drop needs: it's small, accessible, framework-agnostic, and actively maintained. Atlassian's Pragmatic drag-and-drop is the better pick if you need production-grade performance at Jira/Trello scale with zero abstraction overhead.

Key Takeaways

  • react-beautiful-dnd: ~1.2M weekly downloads but no longer maintained by Atlassian — deprecated
  • @dnd-kit: ~2.8M weekly downloads — the community standard, 6KB core, excellent accessibility
  • @atlaskit/pragmatic-drag-and-drop: Atlassian's replacement — tiny (< 4KB), no animation opinions, built for performance
  • @dnd-kit wins for most projects: rich plugin system, sortable preset, collision detection strategies
  • Pragmatic DnD wins for custom, performance-critical implementations (Jira, Confluence, Trello)
  • Both are TypeScript-native and production-proven at scale
PackageWeekly DownloadsStatusBundle Size
react-beautiful-dnd~1.2M⚠️ Deprecated~30KB
@dnd-kit/core~2.8M✅ Active~6KB
@atlaskit/pragmatic-drag-and-drop~180K✅ Active~3.5KB

Legacy downloads of react-beautiful-dnd reflect existing projects, not new installs.

The Full Story

react-beautiful-dnd: The Departed Standard

react-beautiful-dnd was the gold standard for drag-and-drop in React from 2018–2022. Atlassian built it for Trello and open-sourced it. The animations were smooth, the API was ergonomic, and it handled keyboard accessibility better than anything else at the time.

In 2022, Atlassian announced they were no longer maintaining it:

"We no longer recommend react-beautiful-dnd for new projects. We have moved to @atlaskit/pragmatic-drag-and-drop." — Atlassian, 2022

The library still works, but:

  • No security updates
  • No new features
  • No React 19 compatibility guaranteed
  • Issues and PRs are ignored

The ~1.2M weekly downloads are legacy projects that haven't migrated yet. Don't use it for new projects.

@dnd-kit: The Community Standard

@dnd-kit by Claudéric Demers is what react-beautiful-dnd should have evolved into. Built from scratch with modern React in mind:

import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
} from "@dnd-kit/core"
import {
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
  useSortable,
} from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"

function SortableItem({ id }: { id: string }) {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  }

  return (
    <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
      {id}
    </div>
  )
}

function SortableList({ items }: { items: string[] }) {
  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  )

  return (
    <DndContext sensors={sensors} collisionDetection={closestCenter}>
      <SortableContext items={items} strategy={verticalListSortingStrategy}>
        {items.map((id) => (
          <SortableItem key={id} id={id} />
        ))}
      </SortableContext>
    </DndContext>
  )
}

What makes @dnd-kit excellent:

  1. Modular architecture: Core is 6KB. Install only what you need (@dnd-kit/sortable, @dnd-kit/modifiers, @dnd-kit/utilities)
  2. Headless: Zero opinion on styling or animations — you control the UI
  3. Collision detection strategies: closestCenter, closestCorners, rectIntersection, pointerWithin — or write your own
  4. Multiple containers: Drag between lists, grids, trees out of the box
  5. Accessibility first: Screen reader announcements, keyboard navigation, ARIA attributes all handled
  6. Sensors: Pointer (mouse/touch), keyboard, and custom sensors supported
  7. Performance: Uses transform/translate only — no layout thrashing

Pragmatic drag-and-drop: Atlassian's New Approach

After shipping react-beautiful-dnd, Atlassian went back to basics when rebuilding Jira and Confluence. The result was @atlaskit/pragmatic-drag-and-drop — a library that makes zero assumptions:

import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine"
import { useEffect, useRef } from "react"

function DraggableCard({ id, label }: { id: string; label: string }) {
  const ref = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const el = ref.current
    if (!el) return

    return combine(
      draggable({
        element: el,
        getInitialData: () => ({ id }),
      }),
      dropTargetForElements({
        element: el,
        onDrop: ({ source }) => {
          console.log(`Dropped ${source.data.id} onto ${id}`)
        },
      })
    )
  }, [id])

  return <div ref={ref}>{label}</div>
}

The Pragmatic DnD philosophy:

  • No React dependency in the core (framework-agnostic)
  • No animation opinions — build your own with any library
  • No position calculation assumptions — you decide what "drop here" means
  • Platform-specific adapters: element, text, files, external sources
  • Native drag events only — maximum browser compatibility

Why Atlassian chose this approach:

At Jira/Trello scale, even small performance regressions matter. By removing ALL abstractions, Pragmatic DnD gives you direct access to browser drag events with minimal JavaScript overhead.

Feature Comparison

Feature@dnd-kitPragmatic DnDreact-beautiful-dnd
Bundle size (core)6KB3.5KB30KB
Maintenance✅ Active✅ Active❌ Deprecated
React dependencyYesOptionalYes
Built-in animationsVia transforms❌ DIY✅ Yes
Sortable preset✅ @dnd-kit/sortable❌ DIY✅ Yes
Multi-container✅ Built-in✅ Manual✅ Built-in
Accessibility✅ Excellent✅ Via helpers✅ Excellent
TypeScript✅ First-class✅ First-class⚠️ Bolted on
Virtual lists✅ Supported✅ Designed for it⚠️ Hacky
File drag-and-drop❌ Elements only✅ Built-in adapter
External drag sources✅ Built-in adapter
Framework agnostic❌ React-only✅ Yes❌ React-only

When Virtual Lists Matter

For long sortable lists (hundreds to thousands of items), @dnd-kit pairs well with virtual list libraries:

import { useVirtualizer } from "@tanstack/react-virtual"
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable"

function VirtualSortableList({ items }: { items: string[] }) {
  const parentRef = useRef<HTMLDivElement>(null)

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50,
  })

  return (
    <DndContext collisionDetection={closestCenter}>
      <SortableContext items={items} strategy={verticalListSortingStrategy}>
        <div ref={parentRef} style={{ height: 400, overflow: "auto" }}>
          <div style={{ height: virtualizer.getTotalSize() }}>
            {virtualizer.getVirtualItems().map((virtualItem) => (
              <SortableItem
                key={items[virtualItem.index]}
                id={items[virtualItem.index]}
                style={{ position: "absolute", top: virtualItem.start }}
              />
            ))}
          </div>
        </div>
      </SortableContext>
    </DndContext>
  )
}

Pragmatic DnD was specifically designed with virtual lists in mind — its core doesn't need to know about all items upfront.

Migration: react-beautiful-dnd → @dnd-kit

// Before (react-beautiful-dnd):
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"

function Before({ items }: { items: Item[] }) {
  return (
    <DragDropContext onDragEnd={handleDragEnd}>
      <Droppable droppableId="list">
        {(provided) => (
          <ul {...provided.droppableProps} ref={provided.innerRef}>
            {items.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <li
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item.label}
                  </li>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </ul>
        )}
      </Droppable>
    </DragDropContext>
  )
}

// After (@dnd-kit):
import { DndContext, closestCenter } from "@dnd-kit/core"
import { SortableContext, useSortable } from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"

function SortableItem({ item }: { item: Item }) {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: item.id })

  return (
    <li
      ref={setNodeRef}
      style={{ transform: CSS.Transform.toString(transform), transition }}
      {...attributes}
      {...listeners}
    >
      {item.label}
    </li>
  )
}

function After({ items }: { items: Item[] }) {
  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <SortableContext items={items.map(i => i.id)}>
        <ul>
          {items.map((item) => (
            <SortableItem key={item.id} item={item} />
          ))}
        </ul>
      </SortableContext>
    </DndContext>
  )
}

Key differences in migration:

  • No placeholder elements needed
  • No render prop pattern — hooks instead
  • onDragEnd event shape is different — use arrayMove from @dnd-kit/sortable

When to Use Each

Choose @dnd-kit if:

  • You want a React drag-and-drop solution that handles 90% of use cases
  • You need sortable lists, kanban boards, or grid reordering
  • Keyboard accessibility and screen reader support are priorities
  • You want community examples, integrations, and recipes

Choose Pragmatic drag-and-drop if:

  • You're building something that looks like Jira, Trello, or Confluence
  • You need to drag files or text from outside the browser
  • You want maximum control with no abstraction opinions
  • Your team has capacity to build animation and collision logic from scratch
  • Performance is critical at thousands-of-items scale

Don't use react-beautiful-dnd if:

  • Starting a new project in 2026
  • You want security patches or React 19 support

Ecosystem & Community

@dnd-kit has become the community consensus pick for React drag-and-drop since 2022. It has nearly 15,000 GitHub stars and an active maintainer in Claudéric Demers. The documentation site at dndkit.com is comprehensive, with live examples for common patterns including kanban boards, sortable grids, and multi-container dragging. The npm ecosystem has grown around it: you'll find @dnd-kit adapters for Framer Motion animations, recipes for React 18 concurrent mode, and integration guides for virtually every major component library.

Pragmatic drag-and-drop benefits from Atlassian's institutional backing. It's actively developed because Jira, Confluence, and Trello all depend on it. The Atlassian Design System documentation is detailed and includes migration guides from react-beautiful-dnd. However, the community footprint is smaller — you'll find fewer third-party tutorials and ecosystem packages compared to @dnd-kit.

Real-World Adoption

@dnd-kit powers drag-and-drop in a significant portion of React applications built since 2022. Linear, the project management tool, uses @dnd-kit for their issue reordering. Vercel's dashboard uses it for project arrangement. Many Notion alternatives and kanban-style apps built on React have standardized on @dnd-kit. The 2.8M weekly downloads reflect real production use, not just experimental adoption. For the component primitives that these drag-and-drop UIs are built on, see best React component libraries 2026.

Pragmatic drag-and-drop is Atlassian's standard across their cloud products. Jira Software's board view, Confluence's page tree, and Trello's card dragging all run on it. This means it's battle-tested against millions of daily active users at a scale that few other drag-and-drop libraries have seen. When Atlassian says it handles virtual lists well, they mean it handles thousands of Jira issues in a board view without jank. For animation of the drag interactions, see Framer Motion vs Motion One vs AutoAnimate.

Performance & Benchmarks

The performance story between @dnd-kit and Pragmatic DnD is nuanced. For typical kanban boards with 50-200 items, both libraries perform identically in practice — neither produces perceptible lag on modern hardware.

The gap emerges at scale. @dnd-kit's collision detection algorithms need to evaluate every droppable region on each pointer move. With 1,000+ items, this becomes measurable. Pragmatic DnD sidesteps this by making you responsible for collision detection — you can implement a more efficient algorithm tuned to your specific layout. For a Jira-style board with 500 issues across 10 columns, the difference in frame rate during a drag is meaningful.

@dnd-kit's transform/translate approach for dragging avoids layout thrashing, which keeps animations at 60fps for the common case. The library also includes drag overlay support that decouples the dragged item's visual representation from the DOM position, eliminating paint work during drag.

Final Verdict 2026

The decision is clear-cut in 2026: if you're starting a new React project, choose @dnd-kit. It's the community standard with the best documentation, widest ecosystem, and most complete feature set for typical use cases. The accessibility story is excellent, TypeScript support is first-class, and the modular architecture means you only ship what you use.

Choose Pragmatic drag-and-drop only when you genuinely need its specific strengths: file drag targets, external drag sources, or performance at thousands-of-items scale where custom collision detection matters. Be prepared to build more yourself — animations, drag handles, and drop indicators all require custom implementation.

Never start a new project with react-beautiful-dnd. The deprecation is real, React 19 compatibility is uncertain, and both alternatives are strictly better.

Methodology

Download data from npm registry (weekly average, February 2026). Bundle sizes from bundlephobia for core packages. API examples reflect latest stable versions (@dnd-kit 6.x, @atlaskit/pragmatic-drag-and-drop 1.x).

See real-time package metrics on PkgPulse →

Accessibility in Depth

Accessibility is one of the most important factors in choosing a drag-and-drop library, and it's an area where the deprecated react-beautiful-dnd actually set a high bar that both @dnd-kit and Pragmatic DnD have worked to match.

@dnd-kit's accessibility story is built into the core. The library announces drag start, drag over, and drag end events to screen readers automatically using ARIA live regions. Keyboard navigation works out of the box with the KeyboardSensor — pressing Space starts a drag, arrow keys move the dragged item, Space again drops it, and Escape cancels. The announcements are customizable: you can provide your own screenReaderInstructions and announcements configuration to describe what's happening in domain-specific language ("Moved task to Done column" rather than "Item moved to position 3 of 3").

Pragmatic DnD takes a lower-level approach to accessibility. The library provides accessibility utilities that you compose yourself rather than applying automatically. This gives you complete control over ARIA attributes and announcements, but it means you need to implement keyboard navigation from scratch. For teams building custom interfaces, this is often preferable — you can implement exactly the right accessibility pattern for your specific interaction model without fighting a library's assumptions.

The practical implication: if you need a screen-reader-friendly kanban board quickly, @dnd-kit provides it without custom implementation work. If you're building a file tree, a timeline editor, or another non-standard drag interaction, you'll customize accessibility behavior either way, and Pragmatic DnD's lower-level hooks make that customization less awkward.

Animations and Visual Feedback

Neither @dnd-kit nor Pragmatic DnD ships animations out of the box — this is a deliberate design decision in both libraries. react-beautiful-dnd's built-in animations were a selling point for adoption, but they also made it difficult to customize the drag experience. Both modern libraries leave animation entirely to the consuming application.

For @dnd-kit, the recommended animation approach uses CSS transitions applied to the transform property that the library manages. When transition is included in the sortable item's style alongside transform: CSS.Transform.toString(transform), browsers apply hardware-accelerated animations automatically. The result is smooth 60fps animations with a few lines of CSS, no JavaScript animation library required.

Pragmatic DnD users typically reach for Framer Motion or the Web Animations API for more sophisticated effects. Because Pragmatic DnD exposes raw drag events, you can trigger any animation in response to drag state changes. Teams building Jira-like interfaces often implement drop placeholder animations — showing where the card will land — by rendering a separate element that tracks the current drag position.

TypeScript Integration

Both @dnd-kit and Pragmatic DnD are written in TypeScript and ship comprehensive type definitions. The TypeScript experience is noticeably better than react-beautiful-dnd, which was written in JavaScript and has TypeScript definitions that were added later and are sometimes incomplete.

@dnd-kit's types reflect its hook-based API cleanly. The useSortable hook returns a well-typed object, collision detection strategies accept typed arguments, and custom sensor configurations are type-checked. The one area where types can feel loose is data attributes on draggables and drop targets — these are typed as Data extends Record<string, unknown> generics that require explicit typing to get full inference.

Pragmatic DnD's TypeScript coverage is excellent for the core API and the platform-specific adapters. The generic getData / getInitialData pattern follows TypeScript conventions that make data typed through the drag lifecycle. The downside is that the low-level event-based API has more surface area to type than @dnd-kit's hook abstractions, meaning you write more explicit type annotations.

For related React ecosystem comparisons, see best React component libraries 2026. If you're building data-heavy interfaces, TanStack Query v5 vs SWR v3 vs RTK Query covers the server state management layer that often pairs with drag-and-drop UIs. For accessible, sortable table UIs that frequently include drag-and-drop row reordering, see the TanStack Table vs AG Grid vs React Data Grid comparison.

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.