# Drag-and-Drop Libraries in the Plane UI: Inside the Pragmatic Drag-and-Drop Implementation

> Discover the pragmatic drag and drop libraries powering Plane UI reordering. Learn how @atlaskit packages enable seamless Kanban boards, lists, and sidebar interactions.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: internals
- Published: 2026-08-22

---

**The Plane UI relies on Atlassian’s Pragmatic Drag-and-Drop ecosystem—specifically `@atlaskit/pragmatic-drag-and-drop`, `@atlaskit/pragmatic-drag-and-drop-hitbox`, and `@atlaskit/pragmatic-drag-and-drop-auto-scroll` —to power reordering in Kanban boards, lists, and sidebars.**

The `makeplane/plane` repository manages complex project workflows where users constantly rearrange issues, labels, and project states. Understanding which **drag-and-drop libraries in the Plane UI** enable these interactions reveals why the interface remains responsive across large datasets. The codebase explicitly avoids heavy abstraction layers in favor of composable, low-level primitives that integrate directly with React refs and effects.

## Core Atlassian Pragmatic Drag-and-Drop Packages

Plane’s implementation centers on three specific packages from Atlassian’s ecosystem, each pinned to precise versions in [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml).

### @atlaskit/pragmatic-drag-and-drop (Core)

Version `1.7.4` of this library provides the foundational primitives `draggable`, `dropTargetForElements`, and `monitorForElements`. According to the `makeplane/plane` source code, these functions appear throughout the shared UI package and web application:

- In [`packages/ui/src/sortable/draggable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/draggable.tsx), the code imports `combine` and element adapters to wrap components with drag behavior.
- In [`packages/ui/src/sortable/sortable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/sortable.tsx), `monitorForElements` tracks drag events across multiple drop targets for complex sort operations.
- Components in `apps/web`, such as [`projects-list-item.tsx`](https://github.com/makeplane/plane/blob/main/projects-list-item.tsx), initiate drag operations using the `draggable` function with `getInitialData` payloads.

### @atlaskit/pragmatic-drag-and-drop-hitbox

This utility library (version `1.1.0`) supplies spatial detection logic that determines the closest edge of a drop target. This enables visual feedback—like insertion lines—when reordering items. The [`packages/ui/src/sortable/draggable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/draggable.tsx) file imports `closest-edge` helpers, while [`apps/web/core/components/project-states/state-item.tsx`](https://github.com/makeplane/plane/blob/main/apps/web/core/components/project-states/state-item.tsx) uses `attachInstruction` and `extractInstruction` to calculate whether a drop should place an item above, below, or inline with existing elements.

### @atlaskit/pragmatic-drag-and-drop-auto-scroll

Listed at version `1.4.0` in the workspace configuration, this optional package automatically scrolls containers when dragged items approach viewport boundaries. You will find it integrated in long list views such as [`apps/web/core/components/issues/issue-layouts/list/default.tsx`](https://github.com/makeplane/plane/blob/main/apps/web/core/components/issues/issue-layouts/list/default.tsx) and various Kanban boards inside `apps/web`, improving usability for lengthy workflows without manual scrollbar interaction.

## Implementation Patterns in the Codebase

The following snippets demonstrate how these **drag-and-drop libraries in the Plane UI** are wired into React components using hooks and refs.

### Creating a Draggable Element

The `draggable` function from the element adapter attaches behavior to DOM nodes. As implemented in [`packages/ui/src/sortable/draggable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/draggable.tsx):

```tsx
import { draggable } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";

function MyDraggableItem() {
  const ref = useRef<HTMLDivElement | null>(null);

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

    draggable({
      element: el,
      getInitialData: () => ({ id: "my-item-id" }),
    });
  }, []);

  return <div ref={ref}>Drag me!</div>;
}

```

### Detecting Drop Edges with Hitbox Utilities

To enable precise reordering, Plane uses the hitbox package to calculate insertion points. The pattern from [`apps/web/core/components/project-states/state-item.tsx`](https://github.com/makeplane/plane/blob/main/apps/web/core/components/project-states/state-item.tsx) looks like this:

```tsx
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import {
  attachInstruction,
  extractInstruction,
} from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";

function MyDropZone() {
  const ref = useRef<HTMLDivElement | null>(null);

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

    dropTargetForElements({
      element: el,
      canDrop: ({ source }) => source.id !== "my-item-id",
      getData: ({ input }) => ({
        ...attachInstruction({ element: el, input }),
      }),
      onDrop: ({ source, location }) => {
        const edge = extractInstruction(location);
        console.log("Dropped on edge:", edge);
      },
    });
  }, []);

  return <div ref={ref}>Drop here</div>;
}

```

### Enabling Auto-Scroll for Long Lists

For containers with overflow content, Plane registers auto-scroll behavior. This snippet reflects usage in list layouts like [`apps/web/core/components/issues/issue-layouts/list/default.tsx`](https://github.com/makeplane/plane/blob/main/apps/web/core/components/issues/issue-layouts/list/default.tsx):

```tsx
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";

useEffect(() => {
  const cleanup = autoScrollForElements({
    element: scrollContainerRef.current!,
    scrollMargin: 30,
  });
  return cleanup;
}, []);

```

## Critical Source Files

Understanding where these libraries integrate helps when customizing or debugging the **drag-and-drop libraries in the Plane UI**:

- **[`packages/ui/src/sortable/draggable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/draggable.tsx)**: Core wrapper that combines `draggable` primitives with hitbox utilities to create reusable sortable items.

- **[`packages/ui/src/sortable/sortable.tsx`](https://github.com/makeplane/plane/blob/main/packages/ui/src/sortable/sortable.tsx)**: Sets up global monitoring via `monitorForElements` to track items moving between different drop targets.

- **[`apps/web/core/components/project-states/state-item.tsx`](https://github.com/makeplane/plane/blob/main/apps/web/core/components/project-states/state-item.tsx)**: Concrete example of a drop target implementing edge detection for reordering project states.

- **[`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml)**: Declares the exact versions of all three Pragmatic Drag-and-Drop packages (core `1.7.4`, hitbox `1.1.0`, auto-scroll `1.4.0`).

## Summary

- Plane builds its drag-and-drop layer on **Atlassian Pragmatic Drag-and-Drop**, not legacy libraries like `react-beautiful-dnd`.
- The **core library** (`@atlaskit/pragmatic-drag-and-drop`) provides the `draggable` and `dropTargetForElements` primitives used across `packages/ui` and `apps/web`.
- **Hitbox utilities** enable precise edge detection for list reordering, implemented in components like [`state-item.tsx`](https://github.com/makeplane/plane/blob/main/state-item.tsx).
- **Auto-scroll** behavior improves UX for lengthy Kanban boards and issue lists.
- All dependencies are centrally managed in [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml) with pinned versions for consistency.

## Frequently Asked Questions

### Why did Plane choose Pragmatic Drag-and-Drop over alternatives like react-beautiful-dnd?

Atlassian’s library offers a lower-level, more composable API that works with modern React patterns while avoiding the bundle size and maintenance issues of larger abstraction libraries. As seen in `packages/ui/src/sortable`, Plane can mix `draggable` behaviors with custom hitbox logic rather than fighting a high-level component API.

### How does Plane calculate drop positions between list items?

The codebase uses `@atlaskit/pragmatic-drag-and-drop-hitbox` functions like `attachInstruction` and `extractInstruction` to determine the closest edge (top, bottom, left, or right) of a target element. This allows components in `apps/web/core/components` to show insertion lines and compute final sort indices during the `onDrop` event.

### Does the Plane UI support auto-scrolling during drag operations?

Yes. The `apps/web` directory shows integration of `@atlaskit/pragmatic-drag-and-drop-auto-scroll` in list and board layouts. By calling `autoScrollForElements` on container refs, the UI automatically scrolls when users drag items near viewport edges, eliminating the need for manual scroll handling.

### Where are the drag-and-drop library versions defined in the Plane repository?

All versions are declared in the root [`pnpm-workspace.yaml`](https://github.com/makeplane/plane/blob/main/pnpm-workspace.yaml) file. Currently, Plane pins `@atlaskit/pragmatic-drag-and-drop` at `1.7.4`, `@atlaskit/pragmatic-drag-and-drop-hitbox` at `1.1.0`, and `@atlaskit/pragmatic-drag-and-drop-auto-scroll` at `1.4.0`, ensuring consistent behavior across the monorepo's packages and applications.