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

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.

@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:

@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 file imports closest-edge helpers, while 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 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:

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 looks like this:

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:

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:

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.
  • Auto-scroll behavior improves UX for lengthy Kanban boards and issue lists.
  • All dependencies are centrally managed in 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →