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

# Quick start

> Build your first drag and drop interface with dnd-kit in minutes

## Overview

This guide walks you through creating your first drag and drop interface with dnd-kit. You'll learn the fundamental concepts by building a simple draggable item, then progress to creating a sortable list.

<Info>
  This guide uses React examples. For other frameworks, the concepts are identical—only the syntax differs slightly.
</Info>

## Prerequisites

Before starting, make sure you have:

<Steps>
  <Step title="Installed dnd-kit">
    Follow the [installation guide](/installation) to install the necessary packages for your framework.
  </Step>

  <Step title="Basic framework knowledge">
    Familiarity with React hooks (or equivalent in your framework) is helpful.
  </Step>
</Steps>

## Your first draggable

Let's start with the simplest possible example: a single draggable element.

<Steps>
  <Step title="Set up the provider">
    Wrap your application (or the part that needs drag and drop) with `DragDropProvider`:

    ```tsx App.tsx theme={null}
    import {DragDropProvider} from '@dnd-kit/react';

    function App() {
      return (
        <DragDropProvider>
          {/* Your draggable elements will go here */}
        </DragDropProvider>
      );
    }

    export default App;
    ```

    The `DragDropProvider` manages the drag and drop state and coordinates all draggable and droppable elements.
  </Step>

  <Step title="Create a draggable component">
    Use the `useDraggable` hook to make an element draggable:

    ```tsx Draggable.tsx theme={null}
    import {useState} from 'react';
    import {useDraggable} from '@dnd-kit/react';

    export function Draggable() {
      const [element, setElement] = useState<Element | null>(null);
      
      const {isDragging} = useDraggable({
        id: 'draggable-1',
        element,
      });

      return (
        <div
          ref={setElement}
          style={{
            padding: '20px',
            border: '2px solid #666',
            borderRadius: '8px',
            backgroundColor: isDragging ? '#e3f2fd' : '#fff',
            cursor: isDragging ? 'grabbing' : 'grab',
            opacity: isDragging ? 0.5 : 1,
          }}
        >
          Drag me!
        </div>
      );
    }
    ```

    Key points:

    * Each draggable needs a unique `id`
    * Pass the element reference via the `element` prop
    * Use `isDragging` to provide visual feedback
  </Step>

  <Step title="Use your draggable">
    Import and render your draggable component:

    ```tsx App.tsx theme={null}
    import {DragDropProvider} from '@dnd-kit/react';
    import {Draggable} from './Draggable';

    function App() {
      return (
        <DragDropProvider>
          <div style={{padding: '50px'}}>
            <Draggable />
          </div>
        </DragDropProvider>
      );
    }

    export default App;
    ```
  </Step>
</Steps>

<Check>
  You should now be able to drag the element around! The element will follow your cursor and return to its original position when released.
</Check>

## Adding a drop zone

Now let's add a droppable area where you can drop the draggable element.

<Steps>
  <Step title="Create a droppable component">
    Use the `useDroppable` hook:

    ```tsx Droppable.tsx theme={null}
    import {useState} from 'react';
    import {useDroppable} from '@dnd-kit/react';

    export function Droppable({children}: {children: React.ReactNode}) {
      const [element, setElement] = useState<Element | null>(null);
      
      const {isDropTarget} = useDroppable({
        id: 'droppable-1',
        element,
      });

      return (
        <div
          ref={setElement}
          style={{
            minHeight: '200px',
            padding: '20px',
            border: '2px dashed #999',
            borderRadius: '8px',
            backgroundColor: isDropTarget ? '#e8f5e9' : '#f5f5f5',
            transition: 'background-color 0.2s',
          }}
        >
          {children}
        </div>
      );
    }
    ```

    The `isDropTarget` property indicates when a draggable is hovering over this droppable.
  </Step>

  <Step title="Handle drop events">
    Add event handlers to track when items are dropped:

    ```tsx App.tsx theme={null}
    import {DragDropProvider} from '@dnd-kit/react';
    import type {DragEndEvent} from '@dnd-kit/react';
    import {Draggable} from './Draggable';
    import {Droppable} from './Droppable';

    function App() {
      const handleDragEnd = (event: DragEndEvent) => {
        const {source, target} = event.operation;
        
        if (target) {
          console.log(`Dropped ${source.id} on ${target.id}`);
        }
      };

      return (
        <DragDropProvider onDragEnd={handleDragEnd}>
          <div style={{padding: '50px', display: 'flex', gap: '20px'}}>
            <div>
              <h3>Draggable</h3>
              <Draggable />
            </div>
            <div style={{flex: 1}}>
              <h3>Drop Zone</h3>
              <Droppable>
                Drop here!
              </Droppable>
            </div>
          </div>
        </DragDropProvider>
      );
    }

    export default App;
    ```
  </Step>
</Steps>

## Building a sortable list

Now let's create something more practical: a sortable list where you can reorder items by dragging.

<Steps>
  <Step title="Install the helpers package">
    The helpers package provides utilities for common operations like reordering:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @dnd-kit/helpers @dnd-kit/collision
      ```

      ```bash yarn theme={null}
      yarn add @dnd-kit/helpers @dnd-kit/collision
      ```

      ```bash pnpm theme={null}
      pnpm add @dnd-kit/helpers @dnd-kit/collision
      ```

      ```bash bun theme={null}
      bun add @dnd-kit/helpers @dnd-kit/collision
      ```
    </CodeGroup>
  </Step>

  <Step title="Create a sortable item component">
    Use the `useSortable` hook for items in a sortable list:

    ```tsx SortableItem.tsx theme={null}
    import {useState, memo} from 'react';
    import {useSortable} from '@dnd-kit/react/sortable';
    import {directionBiased} from '@dnd-kit/collision';

    interface Props {
      id: string | number;
      index: number;
    }

    export const SortableItem = memo(function SortableItem({id, index}: Props) {
      const [element, setElement] = useState<Element | null>(null);
      
      const {isDragging} = useSortable({
        id,
        index,
        element,
        collisionDetector: directionBiased,
      });

      return (
        <div
          ref={setElement}
          style={{
            padding: '16px 20px',
            marginBottom: '8px',
            backgroundColor: '#fff',
            border: '1px solid #ddd',
            borderRadius: '8px',
            cursor: 'grab',
            opacity: isDragging ? 0.5 : 1,
            boxShadow: isDragging
              ? '0 10px 20px rgba(0,0,0,0.2)'
              : '0 1px 3px rgba(0,0,0,0.1)',
            transition: 'box-shadow 0.2s',
          }}
        >
          {id}
        </div>
      );
    });
    ```

    Key differences from basic draggables:

    * Uses `useSortable` instead of `useDraggable`
    * Requires both `id` and `index` props
    * Uses `directionBiased` collision detection optimized for lists
  </Step>

  <Step title="Create the sortable list">
    Build the list with state management:

    ```tsx SortableList.tsx theme={null}
    import {useState} from 'react';
    import {DragDropProvider} from '@dnd-kit/react';
    import type {DragEndEvent} from '@dnd-kit/react';
    import {move} from '@dnd-kit/helpers';
    import {SortableItem} from './SortableItem';

    export function SortableList() {
      const [items, setItems] = useState([
        'Item 1',
        'Item 2', 
        'Item 3',
        'Item 4',
        'Item 5',
      ]);

      const handleDragEnd = (event: DragEndEvent) => {
        setItems((currentItems) => move(currentItems, event));
      };

      return (
        <DragDropProvider onDragEnd={handleDragEnd}>
          <div style={{maxWidth: '400px', margin: '0 auto', padding: '20px'}}>
            <h2>Sortable List</h2>
            <div>
              {items.map((item, index) => (
                <SortableItem key={item} id={item} index={index} />
              ))}
            </div>
          </div>
        </DragDropProvider>
      );
    }
    ```

    The `move` helper automatically calculates the new array order based on the drag event.
  </Step>
</Steps>

<Check>
  You now have a fully functional sortable list! Try dragging items to reorder them.
</Check>

## Adding visual feedback

Enhance the user experience with a drag overlay that follows the cursor:

```tsx SortableList.tsx theme={null}
import {useState} from 'react';
import {DragDropProvider, DragOverlay} from '@dnd-kit/react';
import type {DragStartEvent, DragEndEvent} from '@dnd-kit/react';
import {move} from '@dnd-kit/helpers';
import {SortableItem} from './SortableItem';

export function SortableList() {
  const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']);
  const [activeId, setActiveId] = useState<string | null>(null);

  const handleDragStart = (event: DragStartEvent) => {
    setActiveId(event.operation.source.id as string);
  };

  const handleDragEnd = (event: DragEndEvent) => {
    setItems((currentItems) => move(currentItems, event));
    setActiveId(null);
  };

  return (
    <DragDropProvider 
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      <div style={{maxWidth: '400px', margin: '0 auto', padding: '20px'}}>
        <h2>Sortable List with Overlay</h2>
        <div>
          {items.map((item, index) => (
            <SortableItem key={item} id={item} index={index} />
          ))}
        </div>
      </div>
      
      <DragOverlay>
        {activeId ? (
          <div style={{
            padding: '16px 20px',
            backgroundColor: '#fff',
            border: '1px solid #ddd',
            borderRadius: '8px',
            boxShadow: '0 10px 30px rgba(0,0,0,0.3)',
          }}>
            {activeId}
          </div>
        ) : null}
      </DragOverlay>
    </DragDropProvider>
  );
}
```

The `DragOverlay` renders a custom element that follows the cursor during drag operations.

## Advanced features

Now that you have the basics down, explore these advanced features:

<CardGroup cols={2}>
  <Card title="Drag handles" icon="hand">
    Add a specific handle that must be grabbed to initiate dragging:

    ```tsx theme={null}
    const handleRef = useRef<HTMLButtonElement>(null);

    const {isDragging} = useDraggable({
      id: 'item',
      element,
      handle: handleRef,
    });
    ```
  </Card>

  <Card title="Modifiers" icon="sliders">
    Restrict movement to an axis or snap to grid:

    ```tsx theme={null}
    import {RestrictToVerticalAxis} from '@dnd-kit/abstract/modifiers';

    <DragDropProvider modifiers={[RestrictToVerticalAxis]}>
      {/* ... */}
    </DragDropProvider>
    ```
  </Card>

  <Card title="Multiple containers" icon="table-cells">
    Create complex layouts with multiple droppable containers and transfer items between them.
  </Card>

  <Card title="Custom sensors" icon="hand-pointer">
    Configure activation constraints and custom input methods:

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

    const sensors = [
      PointerSensor.configure({
        activationConstraint: {
          distance: 10, // 10px movement required
        },
      }),
    ];
    ```
  </Card>
</CardGroup>

## Event lifecycle

Understand the drag and drop event lifecycle:

<Steps>
  <Step title="beforedragstart">
    Fired before a drag operation begins. You can prevent the drag by calling `event.preventDefault()`.
  </Step>

  <Step title="dragstart">
    Fired when a drag operation starts. Perfect for tracking analytics or updating UI state.
  </Step>

  <Step title="dragmove">
    Fired continuously as the draggable moves. Use sparingly for performance.
  </Step>

  <Step title="dragover">
    Fired when a draggable moves over a droppable. Ideal for visual feedback.
  </Step>

  <Step title="dragend">
    Fired when a drag operation completes, whether successful or cancelled. Update your data here.
  </Step>
</Steps>

```tsx theme={null}
<DragDropProvider
  onBeforeDragStart={(event) => {
    console.log('About to start dragging', event.operation.source.id);
  }}
  onDragStart={(event) => {
    console.log('Started dragging', event.operation.source.id);
  }}
  onDragOver={(event) => {
    console.log('Dragging over', event.operation.target?.id);
  }}
  onDragEnd={(event) => {
    console.log('Finished dragging', event.operation);
  }}
>
  {/* ... */}
</DragDropProvider>
```

## Common patterns

### Optimistic updates

Update the UI immediately during drag for a snappier feel:

```tsx theme={null}
function SortableList() {
  const [items, setItems] = useState(['A', 'B', 'C']);

  return (
    <DragDropProvider
      onDragOver={(event) => {
        // Update immediately as user drags
        setItems((items) => move(items, event));
      }}
      onDragEnd={(event) => {
        // Final update (in case dragover was missed)
        setItems((items) => move(items, event));
      }}
    >
      {/* ... */}
    </DragDropProvider>
  );
}
```

### Conditional dropping

Control what can be dropped where:

```tsx theme={null}
const {isDropTarget} = useDroppable({
  id: 'container-1',
  element,
  accept: ['type-a', 'type-b'], // Only accept certain types
});
```

### Disabled items

Temporarily disable dragging:

```tsx theme={null}
const {isDragging} = useDraggable({
  id: 'item-1',
  element,
  disabled: isProcessing, // Disable during async operations
});
```

## Next steps

You've built your first drag and drop interfaces! Continue learning:

<CardGroup cols={2}>
  <Card title="API reference" icon="code" href="/api/abstract/overview">
    Explore the complete API documentation
  </Card>

  <Card title="Examples" icon="sparkles" href="/examples/simple-drag-drop">
    Browse more complex examples and patterns
  </Card>

  <Card title="Accessibility" icon="universal-access" href="/guides/accessibility">
    Learn about keyboard navigation and screen reader support
  </Card>

  <Card title="Performance" icon="gauge-high" href="/guides/performance">
    Optimize your drag and drop for large lists
  </Card>
</CardGroup>
