> ## Documentation Index
> Fetch the complete documentation index at: https://dndkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration guide

> A comprehensive guide to migrate from `@dnd-kit/core` to `@dnd-kit/react`

<Steps>
  <Step title="Update dependencies">
    Update your `package.json` and install the new packages:

    ```json theme={null}
      "dependencies": {
        "@dnd-kit/core": "^x.x.x",      // [!code --]
        "@dnd-kit/sortable": "^x.x.x",  // [!code --]
        "@dnd-kit/utilities": "^x.x.x", // [!code --]
        "@dnd-kit/react": "^x.x.x",     // [!code ++]
        "@dnd-kit/helpers": "^x.x.x",   // [!code ++]
      }
    ```

    After updating your package.json, install the new dependencies with your package manager of choice.
  </Step>

  <Step title="Migrate context provider">
    Update your context provider. The new [DragDropProvider](/react/components/drag-drop-provider) replaces the legacy `DndContext`:

    <CodeGroup>
      ```tsx Before theme={null}
      import {DndContext} from '@dnd-kit/core';

      function App() {
        return (
          <DndContext
            onDragStart={({active}) => {
              console.log(`Started dragging ${active.id}`);
            }}
            onDragEnd={({active, over}) => {
              if (over) {
                console.log(`Dropped ${active.id} over ${over.id}`);
              }
            }}
            onDragCancel={({active}) => {
              console.log(`Cancelled dragging ${active.id}`);
            }}
          >
            <YourComponents />
          </DndContext>
        );
      }
      ```

      ```tsx After {1,6-8,10-24} theme={null}
      import {DragDropProvider} from '@dnd-kit/react';

      function App() {
        return (
          <DragDropProvider
            onDragStart={(event, manager) => {
              const {operation} = event;
              console.log(`Started dragging ${operation.source.id}`);
            }}
            onDragEnd={(event, manager) => {
              const {operation, canceled} = event;
              const {source, target} = operation;

              if (canceled) {
                // Replaces onDragCancel
                console.log(`Cancelled dragging ${source.id}`);
                return;
              }

              if (target) {
                console.log(`Dropped ${source.id} over ${target.id}`);
                // Access rich data
                console.log('Source data:', source.data);
                console.log('Drop position:', operation.position.current);
              }
            }}
          >
            <YourComponents />
          </DragDropProvider>
        );
      }
      ```
    </CodeGroup>

    <Info>
      The new provider gives you access to the `manager` instance in event handlers, enabling more advanced control over the drag and drop system.
    </Info>
  </Step>

  <Step title="Update draggable components">
    Update your [draggable](/concepts/draggable) components using the new [useDraggable](/react/hooks/use-draggable) hook:

    <CodeGroup>
      ```tsx Before theme={null}
      function DraggableItem({id}) {
        const {
          attributes,
          listeners,
          setNodeRef,
          transform
        } = useDraggable({
          id
        });

        return (
          <div
            ref={setNodeRef}
            {...listeners}
            {...attributes}
            style={{
              transform: CSS.Transform.toString(transform)
            }}
          >
            Item {id}
          </div>
        );
      }
      ```

      ```tsx After {2-4,7-8} theme={null}
      function DraggableItem({id}) {
        const draggable = useDraggable({
          id,
        });

        return (
          <div
            ref={draggable.ref}
            className={isDragging ? 'dragging' : ''}
          >
            Item {id}
          </div>
        );
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Update droppable components">
    Update your [droppable](/concepts/droppable) components using the new [useDroppable](/react/hooks/use-droppable) hook:

    <CodeGroup>
      ```tsx Before theme={null}
      function Dropzone() {
        const {setNodeRef, isOver} = useDroppable({
          id: 'drop-zone'
        });

        return (
          <div
            ref={setNodeRef}
            style={{
              background: isOver ? 'lightblue' : 'white'
            }}
          >
            Drop here
          </div>
        );
      }
      ```

      ```tsx After {2,8,10} theme={null}
      function Dropzone() {
        const droppable = useDroppable({
          id: 'drop-zone'
        });

        return (
          <div
            ref={droppable.ref}
            style={{
              background: droppable.isDropTarget ? 'green' : 'white'
            }}
          >
            Drop here
          </div>
        );
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Update drag overlay">
    The [DragOverlay](/react/components/drag-overlay) component has been simplified:

    <CodeGroup>
      ```tsx Before theme={null}
      function App() {
        const [activeId, setActiveId] = useState(null);

        return (
          <DndContext
            onDragStart={() => setActiveId('item')}
            onDragEnd={() => setActiveId(null)}
          >
            <Draggable id="item" />
            <DragOverlay>
              {activeId ? <Item id={activeId} /> : null}
            </DragOverlay>
          </DndContext>
        );
      }
      ```

      ```tsx After {2,5,7-9} theme={null}
      function App() {
        return (
          <DragDropProvider>
            <Draggable id="item" />
            <DragOverlay>
              {source => (
                <Item id={source.id} />
              )}
            </DragOverlay>
          </DragDropProvider>
        );
      }
      ```
    </CodeGroup>

    <Warning>
      Only render the `DragOverlay` component once per `DragDropProvider`. The hooks have no effect when used within the overlay.
    </Warning>
  </Step>

  <Step title="Migrate sortable components">
    Update your sortable components using the new [useSortable](/react/hooks/use-sortable) hook:

    <CodeGroup>
      ```tsx Before theme={null}
      import {useSortable} from '@dnd-kit/sortable';

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

        return (
          <div
            ref={setNodeRef}
            {...attributes}
            {...listeners}
            style={{
              transform: CSS.Transform.toString(transform),
              transition
            }}
          >
            Item {id}
          </div>
        );
      }
      ```

      ```tsx After {1,4-7,10-11} theme={null}
      import {useSortable} from '@dnd-kit/react/sortable';

      function SortableItem({id, index}) {
        const sortable = useSortable({
          id,
          index
        });

        return (
          <div
            ref={sortable.ref}
            className={sortable.isDragging ? 'dragging' : undefined}
          >
            Item {id}
          </div>
        );
      }
      ```
    </CodeGroup>

    Use the array manipulation helpers from `@dnd-kit/helpers` to handle reordering.
  </Step>
</Steps>

## API reference

A quick lookup for common legacy APIs and their new equivalents, organized by category.

### Context & Provider

| Legacy (`@dnd-kit/core`) | New (`@dnd-kit/react`)                                     |
| ------------------------ | ---------------------------------------------------------- |
| `DndContext`             | [`DragDropProvider`](/react/components/drag-drop-provider) |

### Events

| Legacy         | New                                       |
| -------------- | ----------------------------------------- |
| `active`       | `event.operation.source`                  |
| `over`         | `event.operation.target`                  |
| `active.id`    | `event.operation.source.id`               |
| `onDragCancel` | Check `event.canceled` inside `onDragEnd` |

### Sensors

<Note>
  The legacy `MouseSensor` and `TouchSensor` have been merged into a single [`PointerSensor`](/extend/sensors/pointer-sensor) that handles mouse, touch, and pen input via the native Pointer Events API. You can still apply different behavior per input type by passing a function to `activationConstraints` and branching on `event.pointerType` (`'mouse'`, `'touch'`, or `'pen'`):

  ```tsx theme={null}
  import {DragDropProvider} from '@dnd-kit/react';
  import {PointerSensor, PointerActivationConstraints} from '@dnd-kit/dom';

  <DragDropProvider
    sensors={(defaults) => [
      ...defaults.filter((sensor) => sensor !== PointerSensor),
      PointerSensor.configure({
        activationConstraints(event, source) {
          if (event.pointerType === 'touch') {
            return [
              new PointerActivationConstraints.Delay({value: 500, tolerance: {x: 5, y: 5}}),
            ];
          }
          return [new PointerActivationConstraints.Distance({value: 8})];
        },
      }),
    ]}
  >
    {/* ... */}
  </DragDropProvider>
  ```

  If you don't configure it, the default already differentiates pointer types. See [Configuring sensors](/react/guides/sensors) for the React-specific guide and the [PointerSensor docs](/extend/sensors/pointer-sensor) for the full default behavior.
</Note>

| Legacy (`@dnd-kit/core`)   | New (`@dnd-kit/dom`)                                                                                                |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `useSensor` / `useSensors` | Built-in by default. Customize via the `sensors` prop on [`DragDropProvider`](/react/components/drag-drop-provider) |
| `MouseSensor`              | [`PointerSensor`](/extend/sensors/pointer-sensor) from `@dnd-kit/dom`                                               |
| `TouchSensor`              | [`PointerSensor`](/extend/sensors/pointer-sensor) from `@dnd-kit/dom`                                               |
| `PointerSensor`            | [`PointerSensor`](/extend/sensors/pointer-sensor) from `@dnd-kit/dom`                                               |
| `KeyboardSensor`           | [`KeyboardSensor`](/extend/sensors/keyboard-sensor) from `@dnd-kit/dom`                                             |

### Collision detection

| Legacy                                    | New                                                                                                                     |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `collisionDetection` prop on `DndContext` | `collisionDetector` option on [`useDroppable`](/react/hooks/use-droppable) / [`useSortable`](/react/hooks/use-sortable) |
| `pointerWithin`                           | `pointerIntersection` from `@dnd-kit/collision`                                                                         |
| `closestCenter`                           | `closestCenter` from `@dnd-kit/collision`                                                                               |
| `closestCorners`                          | `closestCorners` from `@dnd-kit/collision`                                                                              |

### Modifiers

See the [React modifiers guide](/react/guides/modifiers) for usage examples.

| Legacy                     | New                                                           |
| -------------------------- | ------------------------------------------------------------- |
| `restrictToParentElement`  | `RestrictToElement` from `@dnd-kit/dom/modifiers`             |
| `restrictToWindowEdges`    | `RestrictToWindow` from `@dnd-kit/dom/modifiers`              |
| `restrictToVerticalAxis`   | `RestrictToVerticalAxis` from `@dnd-kit/abstract/modifiers`   |
| `restrictToHorizontalAxis` | `RestrictToHorizontalAxis` from `@dnd-kit/abstract/modifiers` |
| `createSnapModifier`       | `SnapModifier` from `@dnd-kit/abstract/modifiers`             |

### Sortable

<Note>
  `SortableContext` is no longer needed. Sortable items register and coordinate with the [`DragDropProvider`](/react/components/drag-drop-provider) automatically when you use [`useSortable`](/react/hooks/use-sortable) — there's no wrapping context to configure. Use the `type` and `accept` options on `useSortable` to control which items can be sorted together.
</Note>

See the [sortable state management guide](/react/guides/sortable-state-management) for usage examples.

| Legacy                          | New                                |
| ------------------------------- | ---------------------------------- |
| `SortableContext`               | No longer needed — see note above  |
| `arrayMove`                     | `move` from `@dnd-kit/helpers`     |
| `verticalListSortingStrategy`   | Not needed — handled automatically |
| `horizontalListSortingStrategy` | Not needed — handled automatically |
| `rectSortingStrategy`           | Not needed — handled automatically |

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart guide" icon="rocket" href="/react/quickstart">
    Build beautiful drag and drop interfaces in minutes with the new dnd kit
  </Card>

  <Card title="Managing sortable state" icon="list-ol" href="/react/guides/sortable-state-management">
    Use the `move` helper from `@dnd-kit/helpers` or manage state manually
  </Card>

  <Card title="Using modifiers" icon="sliders" href="/react/guides/modifiers">
    Restrict movement to an element, axis, or snap to a grid in React
  </Card>

  <Card title="Customizing feedback" icon="clone" href="/react/guides/feedback">
    Configure drag feedback, clone overlays, and drop animations in React
  </Card>
</CardGroup>
