Stable 0.4.0 · one engine, two adapters

Drag is a continuous thing. So is this engine.

dnd_kit keeps the whole gesture in one pure-Dart runtime — activation, geometry, collision, modifiers, sortable math — and lets Flutter and Jaspr render it. Same curve, same answer, both sides.

dart pub add dnd_kit_flutter
drag a capability → 0 in stack
Capabilities
Sortable Press space to pick up, arrow keys to move between chips and zones, space to drop, escape to cancel.
Keyboard Press space to pick up, arrow keys to move between chips and zones, space to drop, escape to cancel.
Modifiers Press space to pick up, arrow keys to move between chips and zones, space to drop, escape to cancel.
Auto-scroll Press space to pick up, arrow keys to move between chips and zones, space to drop, escape to cancel.
Overlay Press space to pick up, arrow keys to move between chips and zones, space to drop, escape to cancel.
Your stack drop here
Code

Drag and drop in three steps

Wrap an area in a DndScope, mark a draggable and a drop target, then react when they meet. You own the data; dnd_kit reports the move — the same API on Flutter and the web.

main.dart
import 'package:dnd_kit_flutter/dnd_kit_flutter.dart';
import 'package:flutter/widgets.dart';

// 1. Wrap the area in a DndScope.
DndScope(
  child: Column(
    children: [
      // 2. Make anything draggable.
      DndDraggable(
        id: const DndId('card'),
        onDragEnd: (event) {
          // 3. React when it lands on a target.
          if (event.overId == const DndId('inbox')) {
            moveCardToInbox();
          }
        },
        child: const Text('Drag me'),
      ),

      // ...and anything a drop target.
      DndDroppable(
        id: const DndId('inbox'),
        child: const Text('Inbox'),
      ),
    ],
  ),
)
Capabilities

Everything you need to drag

Six things the library ships. Grab any card by its handle and reorder the grid — this section runs on the sortable preset.

One drag engine

A single framework-neutral runtime powers both Flutter and the web. Collision, modifiers and sortable math are computed identically on every adapter.

Keyboard & a11y

Every draggable is operable from the keyboard with a live region announcing pick up, move and drop — accessibility is built in, not bolted on.

Modifiers

Constrain movement to an axis, snap to a grid or clamp to a boundary by composing pure modifier functions on the active transform.

Auto-scroll

Drag past the edge of a scrollable region and it scrolls to follow, with velocity driven by the same DOM-free math the engine ships.

SSR-safe

Pointer-events based, no document listeners and no dart:js_interop at import time — components pre-render on the server and hydrate cleanly.

Sortable presets

Drop in SortableScope + SortableItem for vertical, horizontal and grid reordering, or build your own on the generic draggable layer.

Playground

Try it yourself

Drag the tokens from the pool into any bucket. The zones open a gap where the token will land.

pool · drag into a bucket
1 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
2 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
3 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
4 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
5 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
6 Press space to pick up, arrow keys to move between tokens and zones, space to drop, escape to cancel.
Bucket A0
Bucket B0
Bucket C0
active over state idle