react-beautiful-dnd vs react-dnd vs react-sortable-hoc
Architectural Patterns for Drag-and-Drop in React Applications
react-beautiful-dndreact-dndreact-sortable-hoc

Architectural Patterns for Drag-and-Drop in React Applications

react-beautiful-dnd, react-dnd, and react-sortable-hoc are three distinct approaches to implementing drag-and-drop (DnD) interactions in React. react-beautiful-dnd offers an opinionated, accessible solution optimized for vertical lists and boards, enforcing strict design patterns. react-dnd provides a low-level, highly flexible API based on the HTML5 Drag and Drop backend, allowing for complex custom interactions and multiple backends. react-sortable-hoc uses Higher-Order Components (HOCs) to inject sorting logic, focusing primarily on simple list reordering but relying on older React patterns that conflict with modern Hooks.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-beautiful-dnd033,9321.39 MB642-Apache-2.0
react-dnd021,629231 kB474-MIT
react-sortable-hoc010,886-2895 years agoMIT

Architectural Patterns for Drag-and-Drop in React: A Deep Dive

Implementing drag-and-drop (DnD) in React is deceptively complex. It involves managing pointer events, calculating layout shifts, handling accessibility focus states, and synchronizing DOM updates without causing performance jank. The three libraries in question โ€” react-beautiful-dnd, react-dnd, and react-sortable-hoc โ€” represent three different philosophical approaches to solving this problem. Let's break down how they handle architecture, component composition, and real-world constraints.

๐Ÿ—๏ธ Component Composition: Hooks vs. HOCs vs. Primitives

The way these libraries integrate with your component tree defines your entire development experience. This is often the first architectural decision you make.

react-beautiful-dnd uses a render-prop and hook-friendly approach. It exposes context via components like <DragDropContext>, <Droppable>, and <Draggable>. You provide a function child to access the provided props. This pattern works seamlessly with modern functional components and Hooks.

// react-beautiful-dnd: Render prop pattern
import { Draggable } from 'react-beautiful-dnd';

function TaskItem({ task, index }) {
  return (
    <Draggable draggableId={task.id} index={index}>
      {(provided, snapshot) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          style={{ ...provided.draggableProps.style }}
        >
          {task.content}
        </div>
      )}
    </Draggable>
  );
}

react-dnd historically relied on Higher-Order Components (HOCs) but now fully supports Hooks (useDrag, useDrop). The Hook API is cleaner and avoids the "wrapper hell" of the old HOC approach. It separates the logic of "what can be dragged" from "where it can be dropped" explicitly.

// react-dnd: Hooks API
import { useDrag, useDrop } from 'react-dnd';

function TaskItem({ task }) {
  const [{ isDragging }, dragRef] = useDrag(() => ({
    type: 'TASK',
    item: { id: task.id },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }));

  return (
    <div ref={dragRef} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {task.content}
    </div>
  );
}

react-sortable-hoc relies exclusively on Higher-Order Components (HOCs). You must wrap your component with sortableElement and sortableHandle. This pattern is problematic in modern React because it forces class components or creates complex nesting when trying to use Hooks inside the wrapped component. It injects props rather than exposing a clean API.

// react-sortable-hoc: HOC pattern
import { sortableElement, sortableHandle } from 'react-sortable-hoc';

const DragHandle = sortableHandle(() => <span>:::</span>);

const SortableItem = sortableElement(({ value }) => (
  <div>
    <DragHandle />
    {value}
  </div>
));

// Usage requires passing extra props like 'index' and 'listenTosort'
// <SortableItem index={i} value={item} />

๐ŸŽฏ Scope and Flexibility: Lists vs. Universe

Your choice often depends on whether you are building a simple sorted list or a complex interactive canvas.

react-beautiful-dnd is strictly opinionated. It is designed for vertical lists and grid-based boards (like Trello). It enforces specific rules: you generally cannot drag items outside their immediate parent droppable without complex workarounds. It handles the heavy lifting of accessibility and animations automatically but restricts you from doing weird things.

// react-beautiful-dnd: Strict list structure
<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <div ref={provided.innerRef} {...provided.droppableProps}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {/* ... */}
          </Draggable>
        ))}
        {provided.placeholder}
      </div>
    )}
  </Droppable>
</DragDropContext>

react-dnd is unopinionated and universal. You can drag items between windows, implement custom gestures, or create games. It doesn't assume a list structure. You define the "types" of items and how they interact. This flexibility comes with the cost of implementing your own preview layers and collision logic if you need them.

// react-dnd: Custom drop zone logic
function GameBoard() {
  const [{ canDrop, isOver }, dropRef] = useDrop(() => ({
    accept: 'GAME_PIECE',
    drop: (item) => { /* custom logic */ },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }));

  return <div ref={dropRef} className={isOver ? 'active' : ''}>Drop Zone</div>;
}

react-sortable-hoc is scoped purely to sorting lists. It assumes a 1:1 relationship between items and indices. It lacks native support for nested lists, grids, or complex board layouts without significant hacking. It is a single-purpose tool for reordering arrays.

// react-sortable-hoc: Simple array sorting
const SortableList = sortableContainer(({ items }) => (
  <ul>
    {items.map((value, index) => (
      <SortableItem key={`item-${index}`} index={index} value={value} />
    ))}
  </ul>
));

โ™ฟ Accessibility and Animation: Built-in vs. DIY

Accessibility (a11y) is the hardest part of DnD to get right. Moving DOM nodes while maintaining keyboard focus and screen reader announcements requires rigorous engineering.

react-beautiful-dnd is the gold standard here. It automatically manages ARIA attributes, keyboard navigation (arrow keys to move), and focus retention. It also includes a physics-based animation engine that smoothly transitions elements without layout thrashing. You get this out of the box.

// react-beautiful-dnd: Automatic a11y and animation
// No extra code needed for keyboard support or smooth sliding
<Draggable draggableId="task-1" index={0}>
  {(provided) => (
    <div
      ref={provided.innerRef}
      {...provided.draggableProps}
      {...provided.dragHandleProps}
    >
      Accessible Task
    </div>
  )}
</Draggable>

react-dnd provides the logic but not the UI polish. It does not automatically animate elements or manage ARIA states for you. You must build the visual feedback (using react-dnd-html5-backend or custom layers) and ensure keyboard accessibility manually. This is powerful but risky for teams without deep a11y expertise.

// react-dnd: Manual animation and a11y required
// You must calculate styles based on drag state
const [{ isDragging }, dragRef] = useDrag({
  type: 'BOX',
  item: { id },
  collect: (monitor) => ({
    isDragging: monitor.isDragging(),
  }),
});

// You must apply transforms manually for smooth movement
const style = { opacity: isDragging ? 0.4 : 1, transform: 'translate(...)' };

react-sortable-hoc provides basic keyboard support (pressing space to lift, arrows to move), but it is less robust than react-beautiful-dnd. The animations are CSS-transform based and can sometimes struggle with complex layouts or overflow containers. It feels lighter but less polished.

// react-sortable-hoc: Basic helper props
// Helper functions provided for transitions, but less configurable
const SortableItem = sortableElement(({ value, style }) => (
  <li style={style}>{value}</li>
));

โš ๏ธ Maintenance and Future-Proofing

A critical architectural factor is the long-term viability of the library.

react-beautiful-dnd is in maintenance mode. The original maintainers have shifted focus to a new library called @dnd-kit, which is more modular and supports a wider range of use cases. While react-beautiful-dnd is stable and widely used, new projects should strongly consider @dnd-kit or react-dnd to avoid future migration costs. It is not "dead," but it is not evolving.

react-dnd is actively maintained and widely adopted in enterprise environments. Its decoupled architecture (core logic separate from backend) ensures it remains relevant even as React evolves. It is a safe long-term bet for complex applications.

react-sortable-hoc has seen very little activity recently. Its reliance on HOCs makes it increasingly difficult to integrate with modern React patterns (like concurrent rendering and server components). It is effectively legacy technology.

๐Ÿ“Š Summary: Key Differences

Featurereact-beautiful-dndreact-dndreact-sortable-hoc
Primary Use CaseLists & Kanban BoardsComplex, Custom InteractionsSimple List Sorting
Integration PatternRender Props / ContextHooks (or HOCs)Higher-Order Components (HOC)
Accessibilityโœ… Excellent (Built-in)โš ๏ธ Manual Implementationโšช Basic Support
Animationsโœ… Smooth, Physics-basedโš ๏ธ Manual / Customโšช CSS Transforms
Flexibility๐Ÿ”’ Low (Opinionated)๐Ÿš€ High (Unopinionated)๐Ÿ”’ Low (List only)
Modern React Readyโœ… Yesโœ… YesโŒ No (HOC friction)
Maintenance Status๐Ÿ”ถ Maintenance Modeโœ… Activeโš ๏ธ Stale

๐Ÿ’ก The Big Picture

react-beautiful-dnd is the "appliance" approach. It works beautifully out of the box for standard lists and boards, enforcing best practices for accessibility and animation. Use it if you need a Trello-like board tomorrow and don't need to customize the physics. However, be aware of its maintenance status.

react-dnd is the "toolkit" approach. It gives you the raw materials to build any DnD interaction imaginable. It requires more engineering effort but pays off in flexibility and control. It is the correct choice for complex dashboards, design tools, or games.

react-sortable-hoc is the "legacy shortcut." It solves a narrow problem quickly but introduces architectural debt via HOCs. In 2024 and beyond, there is almost no reason to choose this over the other two options for new development.

Final Thought: If you are building a standard list, react-beautiful-dnd (or its successor @dnd-kit) is your fastest path to a high-quality result. If you are building a platform where DnD is a core, complex feature, react-dnd provides the architectural foundation you need. Avoid react-sortable-hoc unless you are maintaining an existing codebase that already depends on it.

How to Choose: react-beautiful-dnd vs react-dnd vs react-sortable-hoc

  • react-beautiful-dnd:

    Choose react-beautiful-dnd if you need a polished, accessible DnD experience for standard lists or kanban boards with minimal configuration. It is ideal for teams that want strict enforcement of accessibility standards and consistent animation behavior without managing low-level events. Note that while maintenance has slowed, it remains the standard for simple, high-quality list interactions, though migration to its successor (@dnd-kit) should be considered for new greenfield projects.

  • react-dnd:

    Choose react-dnd if your application requires complex, non-standard DnD interactions, such as dragging between different windows, custom touch backends, or intricate visual feedback that deviates from standard list behavior. It is the best fit for architectural scenarios where you need full control over the drag lifecycle, multiple backend support (HTML5, Touch, Test), and the ability to build custom primitives from scratch.

  • react-sortable-hoc:

    Avoid choosing react-sortable-hoc for new projects. Its reliance on Higher-Order Components (HOCs) creates significant friction when used with modern React Hooks and functional components. While it solves simple sorting needs quickly, the architectural debt of wrapping components and the lack of active modernization make it a poor choice compared to the flexibility of react-dnd or the accessibility of react-beautiful-dnd.

README for react-beautiful-dnd

โš ๏ธ Maintenance & support

This library continues to be relied upon heavily by Atlassian products, but we are focused on other priorities right now and have no current plans for further feature development or improvements.

It will continue to be here on GitHub and we will still make critical updates (e.g. security fixes, if any) as required, but will not be actively monitoring or replying to issues and pull requests.

We recommend that you donโ€™t raise issues or pull requests, as they will not be reviewed or actioned until further notice.


react beautiful dnd logo

react-beautiful-dnd (rbd)

Beautiful and accessible drag and drop for lists with React

CircleCI branch npm

quote application example

Play with this example if you want!

Core characteristics

  • Beautiful and natural movement of items ๐Ÿ’
  • Accessible: powerful keyboard and screen reader support โ™ฟ๏ธ
  • Extremely performant ๐Ÿš€
  • Clean and powerful api which is simple to get started with
  • Plays extremely well with standard browser interactions
  • Unopinionated styling
  • No creation of additional wrapper dom nodes - flexbox and focus management friendly!

Get started ๐Ÿ‘ฉโ€๐Ÿซ

We have created a free course on egghead.io ๐Ÿฅš to help you get started with react-beautiful-dnd as quickly as possible.

course-logo

Currently supported feature set โœ…

  • Vertical lists โ†•
  • Horizontal lists โ†”
  • Movement between lists (โ–ค โ†” โ–ค)
  • Virtual list support ๐Ÿ‘พ - unlocking 10,000 items @ 60fps
  • Combining items
  • Mouse ๐Ÿญ, keyboard ๐ŸŽนโ™ฟ๏ธ and touch ๐Ÿ‘‰๐Ÿ“ฑ (mobile, tablet and so on) support
  • Multi drag support
  • Incredible screen reader support โ™ฟ๏ธ - we provide an amazing experience for english screen readers out of the box ๐Ÿ“ฆ. We also provide complete customisation control and internationalisation support for those who need it ๐Ÿ’–
  • Conditional dragging and conditional dropping
  • Multiple independent lists on the one page
  • Flexible item sizes - the draggable items can have different heights (vertical lists) or widths (horizontal lists)
  • Add and remove items during a drag
  • Compatible with semantic <table> reordering - table pattern
  • Auto scrolling - automatically scroll containers and the window as required during a drag (even with keyboard ๐Ÿ”ฅ)
  • Custom drag handles - you can drag a whole item by just a part of it
  • Able to move the dragging item to another element while dragging (clone, portal) - Reparenting your <Draggable />
  • Create scripted drag and drop experiences ๐ŸŽฎ
  • Allows extensions to support for any input type you like ๐Ÿ•น
  • ๐ŸŒฒ Tree support through the @atlaskit/tree package
  • A <Droppable /> list can be a scroll container (without a scrollable parent) or be the child of a scroll container (that also does not have a scrollable parent)
  • Independent nested lists - a list can be a child of another list, but you cannot drag items from the parent list into a child list
  • Server side rendering (SSR) compatible - see resetServerContext()
  • Plays well with nested interactive elements by default

Motivation ๐Ÿค”

react-beautiful-dnd exists to create beautiful drag and drop for lists that anyone can use - even people who cannot see. For a good overview of the history and motivations of the project you can take a look at these external resources:

Not for everyone โœŒ๏ธ

There are a lot of libraries out there that allow for drag and drop interactions within React. Most notable of these is the amazing react-dnd. It does an incredible job at providing a great set of drag and drop primitives which work especially well with the wildly inconsistent html5 drag and drop feature. react-beautiful-dnd is a higher level abstraction specifically built for lists (vertical, horizontal, movement between lists, nested lists and so on). Within that subset of functionality react-beautiful-dnd offers a powerful, natural and beautiful drag and drop experience. However, it does not provide the breadth of functionality offered by react-dnd. So react-beautiful-dnd might not be for you depending on what your use case is.

Documentation ๐Ÿ“–

About ๐Ÿ‘‹

Sensors ๐Ÿ”‰

The ways in which somebody can start and control a drag

API ๐Ÿ‹๏ธโ€

diagram

Guides ๐Ÿ—บ

Patterns ๐Ÿ‘ทโ€

Support ๐Ÿ‘ฉโ€โš•๏ธ

Read this in other languages ๐ŸŒŽ

Creator โœ๏ธ

Alex Reardon @alexandereardon

Alex is no longer personally maintaning this project. The other wonderful maintainers are carrying this project forward.

Maintainers

Collaborators ๐Ÿค