entropyconquers/react-native-reanimated-dnd/reanimated-dnd

Claude Code and agent skill by entropyconquers/react-native-reanimated-dnd

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Integrate react-native-reanimated-dnd for drag-and-drop, sortable lists, sortable grids, and drop zones in React Native apps. Covers components, hooks, and all configuration options.

Install

npx vskill@latest install entropyconquers/react-native-reanimated-dnd/reanimated-dnd

SKILL.md

react-native-reanimated-dnd Integration Skill

Version: 2.0.0 Category: UI / Drag and Drop Platform: React Native (requires react-native-reanimated >=4.2.0, react-native-gesture-handler >=2.28.0, react-native-worklets >=0.7.0)


Overview

react-native-reanimated-dnd provides performant drag-and-drop primitives for React Native. It offers both high-level components and low-level hooks for:

  • Drag & Drop: Move items between drop zones
  • Sortable Lists: Vertical and horizontal reorderable lists
  • Sortable Grids: 2D grids with insert or swap reordering
  • Constraints: Axis locking, bounded dragging, collision detection
  • Dynamic Heights: Auto-measuring variable-height items in lists

All animations run on the UI thread via Reanimated worklets.


Installation

bash
npm install react-native-reanimated-dnd
# or
yarn add react-native-reanimated-dnd
Peer dependencies (must be installed separately)
bash
npm install react-native-reanimated react-native-gesture-handler react-native-worklets
Required setup

Wrap your app root with GestureHandlerRootView:

tsx
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* Your app content */}
</GestureHandlerRootView>
);
}

Core Architecture

DropProvider (context - required for Draggable/Droppable)
├── Draggable (items that can be picked up)
│ └── Draggable.Handle (optional restricted drag area)
└── Droppable (zones that accept drops)
Sortable (self-contained vertical/horizontal list)
├── SortableItem (individual reorderable item)
│ └── SortableItem.Handle (optional restricted drag area)
SortableGrid (self-contained 2D grid)
├── SortableGridItem (individual grid cell)
│ └── SortableGridItem.Handle (optional restricted drag area)

Key rule: All data items MUST have an id: string property for tracking.


Pattern 1: Basic Drag & Drop

Use DropProvider + Draggable + Droppable to move items into drop zones.

tsx
import {
DropProvider,
Draggable,
Droppable,
} from 'react-native-reanimated-dnd';
function DragDropExample() {
const [droppedItem, setDroppedItem] = useState<string | null>(null);
return (
<DropProvider>
<View style={styles.items}>
<Draggable data={{ id: '1', label: 'Item A' }}>
<View style={styles.item}>
<Text>Item A</Text>
</View>
</Draggable>
<Draggable data={{ id: '2', label: 'Item B' }}>
<View style={styles.item}>
<Text>Item B</Text>
</View>
</Draggable>
</View>
<Droppable onDrop={(data) => setDroppedItem(data.label)}>
<View style={styles.dropZone}>
<Text>{droppedItem ?? 'Drop here'}</Text>
</View>
</Droppable>
</DropProvider>
);
}
Draggable Props
PropTypeDefaultDescription
dataTDatarequiredPayload passed to drop handlers
draggableIdstringautoUnique identifier
dragDisabledbooleanfalseDisable dragging
preDragDelaynumber0Delay in ms before drag starts
dragAxis`"x" \"y" \"both"`"both"Constrain movement axis
dragBoundsRefRefObject<View>-Constrain within a view
collisionAlgorithm`"center" \"intersect" \"contain"`"intersect"How to detect overlap with droppables
animationFunction(toValue: number) => number-Custom return animation
onDragStart(data: TData) => void-Called when drag begins
onDragEnd(data: TData) => void-Called when drag ends
onDragging({ x, y, tx, ty, itemData }) => void-Real-time position updates
onStateChange(state: DraggableState) => void-State transition callback
Droppable Props
PropTypeDefaultDescription
onDrop(data: TData) => voidrequiredHandle dropped items
dropDisabledbooleanfalseDisable dropping
capacitynumber1Max items allowed
dropAlignmentDropAlignment"center"Position alignment for dropped items
dropOffset{ x: number, y: number }-Fine-tune position after alignment
activeStyleStyleProp<ViewStyle>-Style applied when item hovers over
onActiveChange(isActive: boolean) => void-Called when hover state changes
droppableIdstringautoUnique identifier for the drop zone
DropProvider Props
PropTypeDescription
onDroppedItemsUpdate(items: DroppedItemsMap) => voidTrack items across all zones
onDragging({ x, y, tx, ty, itemData }) => voidGlobal drag position tracking
onDragStart(data) => voidAny drag begins
onDragEnd(data) => voidAny drag ends
onLayoutUpdateComplete() => voidCalled when layout updates finish
DropAlignment values

"center" | "top-left" | "top-center" | "top-right" | "center-left" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right"


Pattern 2: Drag Handles

Restrict the draggable area to a specific handle region using Draggable.Handle:

tsx
<Draggable data={{ id: '1', label: 'Card' }}>
<View style={styles.card}>
<Draggable.Handle>
<View style={styles.handleBar}>
<Text>Drag here</Text>
</View>
</Draggable.Handle>
<View style={styles.cardContent}>
<Text>This area does NOT initiate drag</Text>
</View>
</View>
</Draggable>

The same pattern works for sortable items with SortableItem.Handle.


Pattern 3: Vertical Sortable List

Use the Sortable component for a reorderable list:

tsx
import { Sortable, SortableItem } from 'react-native-reanimated-dnd';
interface Item {
id: string;
title: string;
}
const ITEM_HEIGHT = 60;
function SortableListExample() {
const [items, setItems] = useState<Item[]>([
{ id: '1', title: 'First' },
{ id: '2', title: 'Second' },
{ id: '3', title: 'Third' },
]);
const renderItem = useCallback(({ item, ...props }) => (
<SortableItem
key={item.id}
id={item.id}
data={item}
onMove={(id, from, to) => {
setItems(prev => {
const next = [...prev];
const [moved] = next.splice(from, 1);
next.splice(to, 0, moved);
return next;
});
}}
{...props}
>
<View style={styles.listItem}>
<Text>{item.title}</Text>
</View>
</SortableItem>
), []);
return (
<Sortable
data={items}
renderItem={renderItem}
itemHeight={ITEM_HEIGHT}
/>
);
}
Sortable Props
PropTypeDefaultDescription
dataTData[]requiredItems (each must have id: string)
renderItem(props) => ReactNoderequiredItem renderer
direction`"vertical" \"horizontal"`"vertical"List direction
itemHeight`number \number[] \(item, i) => number`-Item height (required for vertical)
itemWidthnumber-Item width (required for horizontal)
gapnumber0Gap between items (horizontal only)
paddingHorizontalnumber0Container padding (horizontal only)
enableDynamicHeightsbooleanfalseAuto-measure item heights
estimatedItemHeightnumber60Fallback height for unmeasured items
onHeightsMeasured(heights) => void-Called with measured heights
useFlatListbooleantrueUse FlatList for virtualization
itemKeyExtractor(item, index) => stringitem.idCustom key extraction function
styleStyleProp<ViewStyle>-ScrollView/FlatList style
contentContainerStyleStyleProp<ViewStyle>-Content container style
SortableItem Props
PropTypeDescription
idstringUnique item identifier
dataTItem data
onMove(id, from, to) => voidCalled on position change
onDragStart(id, position) => voidDrag started
onDrop(id, position, allPositions?) => voidItem dropped
onDragging(id, overItemId, yPosition) => voidReal-time drag position
styleStyleProp<ViewStyle>Container style
animatedStyleStyleProp<ViewStyle>Animated style

Pattern 4: Horizontal Sortable List

tsx
import {
Sortable,
SortableItem,
SortableDirection,
} from 'react-native-reanimated-dnd';
const ITEM_WIDTH = 120;
function HorizontalSortableExample() {
const [items, setItems] = useState([
{ id: '1', label: 'Tag A' },
{ id: '2', label: 'Tag B' },
{ id: '3', label: 'Tag C' },
]);
const renderItem = useCallback(({ item, ...props }) => (
<SortableItem
key={item.id}
id={item.id}
data={item}
onMove={(id, from, to) => {
setItems(prev => {
const next = [...prev];
const [moved] = next.splice(from, 1);
next.splice(to, 0, moved);
return next;
});
}}
{...props}
>
<View style={styles.tag}>
<Text>{item.label}</Text>
</View>
</SortableItem>
), []);
return (
<Sortable
data={items}
renderItem={renderItem}
direction={SortableDirection.Horizontal}
itemWidth={ITEM_WIDTH}
gap={12}
paddingHorizontal={12}
/>
);
}

Pattern 5: Sortable Grid

tsx
import {
SortableGrid,
SortableGridItem,
GridOrientation,
GridStrategy,
} from 'react-native-reanimated-dnd';
function GridExample() {
const [items, setItems] = useState([
{ id: '1', label: 'A' },
{ id: '2', label: 'B' },
{ id: '3', label: 'C' },
{ id: '4', label: 'D' },
{ id: '5', label: 'E' },
{ id: '6', label: 'F' },
]);
const renderItem = useCallback(({ item, ...props }) => (
<SortableGridItem
key={item.id}
id={item.id}
data={item}
onMove={(id, from, to) => {
setItems(prev => {
const next = [...prev];
const [moved] = next.splice(from, 1);
next.splice(to, 0, moved);
return next;
});
}}
{...props}
>
<View style={styles.gridCell}>
<Text>{item.label}</Text>
</View>
</SortableGridItem>
), []);
return (
<SortableGrid
data={items}
renderItem={renderItem}
dimensions={{
columns: 3,
itemWidth: 100,
itemHeight: 100,
rowGap: 8,
columnGap: 8,
}}
orientation={GridOrientation.Vertical}
strategy={GridStrategy.Insert}
/>
);
}
SortableGrid Props
PropTypeDefaultDescription
dataTData[]requiredGrid items (each must have id: string)
renderItem(props) => ReactNoderequiredItem renderer
dimensionsGridDimensionsrequiredGrid configuration (see below)
orientation`"vertical" \"horizontal"`"vertical"Grid orientation
strategy`"insert" \"swap"`"insert"How items reorder: insert shifts others, swap exchanges two
scrollEnabledbooleantrueEnable scrolling
itemKeyExtractor(item, index) => stringitem.idCustom key extraction
styleStyleProp<ViewStyle>-ScrollView style
contentContainerStyleStyleProp<ViewStyle>-Content style
GridDimensions

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
964
Repository forks
38
Repository npm downloads, 7 days
27,257
7-day trend score
58

Stars and forks are for the whole GitHub repository, not this skill alone. Downloads are for the repository's npm package. Refreshed 18 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/entropyconquers/react-native-reanimated-dnd/reanimated-dnd/badge)](https://verified-skill.com/skills/entropyconquers/react-native-reanimated-dnd/reanimated-dnd)

Something wrong with this skill or its page? Tell us.