[{"data":1,"prerenderedAt":416},["ShallowReactive",2],{"article-drag-and-drop-vue3":3},{"id":4,"title":5,"body":6,"date":407,"description":408,"extension":409,"meta":410,"navigation":411,"path":412,"seo":413,"stem":414,"__hash__":415},"articles\u002Farticles\u002Fdrag-and-drop-vue3.md","Picking a Drag and Drop Library for Vue 3",{"type":7,"value":8,"toc":396},"minimark",[9,13,16,23,28,31,35,47,58,68,71,75,78,87,92,95,99,106,110,141,145,159,163,313,317,320,329,332,336],[10,11,12],"p",{},"I recently had to pick a drag and drop library for a Vue 3 project: a kanban board where cards move across columns, with each state change persisted to the backend. Simple enough in theory, but the choice of library turned out to matter more than I expected.",[10,14,15],{},"Here's what I found after evaluating the three main options.",[10,17,18],{},[19,20],"img",{"alt":21,"src":22},"Pragmatic drag and drop in action — cards being dragged across Confluence, Jira, and Trello columns","\u002Farticles\u002Fpragmatic-dnd-demo.png",[24,25,27],"h2",{"id":26},"the-use-case","The use case",[10,29,30],{},"A board with a few named columns, draggable cards that move freely within and across them, and a backend write on every drop. The columns might grow over time. Nothing exotic, but enough to expose the rough edges of each library.",[24,32,34],{"id":33},"sortablejs-vuedraggable","SortableJS \u002F vuedraggable",[10,36,37,38,42,43,46],{},"The default answer in the Vue ecosystem. ",[39,40,41],"code",{},"vuedraggable"," is a Vue wrapper around SortableJS with a component-based API and ",[39,44,45],{},"v-model"," integration for cross-list dragging.",[10,48,49,53,54,57],{},[50,51,52],"strong",{},"Strengths:"," Simple declarative API. The ",[39,55,56],{},"group"," prop makes cross-list dragging almost trivial. Built-in animation with a single prop. Large community with lots of real-world examples.",[10,59,60,63,64,67],{},[50,61,62],{},"Weaknesses:"," The Vue 3 version (",[39,65,66],{},"vue.draggable.next",") has had no meaningful updates in over six years. It does not use the native HTML5 drag and drop API, so cross-window dragging is out. Bundle size is larger than the alternatives. Visual feedback control is limited.",[10,69,70],{},"The staleness is the main issue. For a project with a long runway, building on a wrapper with no active maintenance is a risk I didn't want to carry.",[24,72,74],{"id":73},"formkit-drag-and-drop","FormKit drag and drop",[10,76,77],{},"A newer library from the FormKit team. Framework-agnostic core with Vue and React wrappers. Instead of manipulating the DOM, it updates a reactive data model — which aligns well with how Vue thinks about state.",[10,79,80,82,83,86],{},[50,81,52],{}," The ",[39,84,85],{},"useDragAndDrop"," composable feels native in a Vue 3 codebase. Lightweight core. Actively developed.",[10,88,89,91],{},[50,90,62],{}," Still pre-1.0 (version 0.3 at the time of writing). Keyboard navigation is incomplete. Mobile behavior has inconsistencies. No meaningful production track record yet.",[10,93,94],{},"Promising direction, but too early to bet on in a production context.",[24,96,98],{"id":97},"pragmatic-drag-and-drop-atlassian","Pragmatic drag and drop (Atlassian)",[10,100,101,102,105],{},"Atlassian's current drag and drop framework — the successor to ",[39,103,104],{},"react-beautiful-dnd",", and what powers Trello, Jira, and Confluence today. Headless, framework-agnostic, built on the native HTML5 drag and drop API.",[10,107,108],{},[50,109,52],{},[111,112,113,117,120,123,126,129,132,135],"ul",{},[114,115,116],"li",{},"Tiny core (~4.7KB) with optional add-ons loaded on demand",[114,118,119],{},"Fully framework-agnostic — works with Vue, React, Svelte, Angular, or vanilla JS",[114,121,122],{},"Native HTML5 API means cross-window dragging and external file drops work out of the box",[114,124,125],{},"Deferred loading compatible, so it doesn't affect initial page load",[114,127,128],{},"Battle-tested at Trello and Jira scale",[114,130,131],{},"Headless: no visual opinions, full control over feedback and animation",[114,133,134],{},"Automatic DOM reconciliation when elements are destroyed and recreated by the framework",[114,136,137,140],{},[39,138,139],{},"@atlaskit\u002Fpragmatic-drag-and-drop-unit-testing"," — a dedicated package with helpers to simulate full drag and drop operations in Vitest, without a real browser. This solves a genuinely painful problem: the native HTML5 drag and drop API is notoriously hard to test headlessly. No other library in this comparison offers anything equivalent.",[10,142,143],{},[50,144,62],{},[111,146,147,153,156],{},[114,148,149,150,152],{},"Lower-level API means more setup than ",[39,151,41],{},"'s declarative approach",[114,154,155],{},"Documentation is React-centric; Vue examples are community-contributed",[114,157,158],{},"Some optional packages (drop indicators, accessibility controls) are React-specific and need custom reimplementation in Vue — though these are purely visual and the core library is fully usable as-is",[24,160,162],{"id":161},"comparison","Comparison",[164,165,166,185],"table",{},[167,168,169],"thead",{},[170,171,172,176,179,182],"tr",{},[173,174,175],"th",{},"Criteria",[173,177,178],{},"SortableJS",[173,180,181],{},"FormKit DnD",[173,183,184],{},"Pragmatic DnD",[186,187,188,203,217,229,240,251,262,276,290,301],"tbody",{},[170,189,190,194,197,200],{},[191,192,193],"td",{},"Vue 3 support",[191,195,196],{},"Wrapper",[191,198,199],{},"Yes",[191,201,202],{},"Yes (native)",[170,204,205,208,211,214],{},[191,206,207],{},"Bundle (core)",[191,209,210],{},"~12KB",[191,212,213],{},"~5KB",[191,215,216],{},"~4.7KB",[170,218,219,222,225,227],{},[191,220,221],{},"Native HTML5 API",[191,223,224],{},"No",[191,226,224],{},[191,228,199],{},[170,230,231,234,236,238],{},[191,232,233],{},"Cross-window drag",[191,235,224],{},[191,237,224],{},[191,239,199],{},[170,241,242,245,247,249],{},[191,243,244],{},"File drop support",[191,246,224],{},[191,248,224],{},[191,250,199],{},[170,252,253,256,258,260],{},[191,254,255],{},"Deferred loading",[191,257,224],{},[191,259,224],{},[191,261,199],{},[170,263,264,267,270,273],{},[191,265,266],{},"Production scale",[191,268,269],{},"Medium",[191,271,272],{},"Early stage",[191,274,275],{},"Trello, Jira",[170,277,278,281,284,287],{},[191,279,280],{},"Maintenance",[191,282,283],{},"Low activity",[191,285,286],{},"Active (pre-1.0)",[191,288,289],{},"Active (Atlassian)",[170,291,292,295,297,299],{},[191,293,294],{},"Unit testing package",[191,296,224],{},[191,298,224],{},[191,300,199],{},[170,302,303,306,309,311],{},[191,304,305],{},"Setup complexity",[191,307,308],{},"Low",[191,310,308],{},[191,312,269],{},[24,314,316],{"id":315},"what-i-chose-and-why","What I chose, and why",[10,318,319],{},"Pragmatic drag and drop. It is the only library that combines a minimal bundle, native HTML5 API capabilities, dedicated unit testing support, and proven reliability at scale — all actively maintained. Its integration with Vue 3 lifecycle hooks is clean, and the DOM reconciliation behavior handles the cases where Vue destroys and recreates elements without any extra wiring.",[10,321,322,323,325,326,328],{},"The setup cost is real compared to ",[39,324,41],{},". There is no ",[39,327,45],{}," shortcut; you wire the drag handlers manually. But that explicitness is also what gives you full control over visual feedback and state transitions — which matters in a production interface where the default behaviors are never quite right anyway.",[10,330,331],{},"Some optional packages (drop indicators, accessibility controls) have React-specific implementations and need to be written in Vue. In practice these are small, self-contained visual components, and having to write them means they match your design system exactly rather than working around someone else's defaults.",[24,333,335],{"id":334},"references","References",[111,337,338,347,354,361,368,375,382,389],{},[114,339,340],{},[341,342,346],"a",{"href":343,"rel":344},"https:\u002F\u002Fatlassian.design\u002Fcomponents\u002Fpragmatic-drag-and-drop",[345],"nofollow","Atlassian — Pragmatic drag and drop documentation",[114,348,349],{},[341,350,353],{"href":351,"rel":352},"https:\u002F\u002Fwww.atlassian.com\u002Fblog\u002Fdesign\u002Fdesigned-for-delight-built-for-performance",[345],"Atlassian Blog — \"Designed for delight, built for performance\"",[114,355,356],{},[341,357,360],{"href":358,"rel":359},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@atlaskit\u002Fpragmatic-drag-and-drop",[345],"npm — @atlaskit\u002Fpragmatic-drag-and-drop",[114,362,363],{},[341,364,367],{"href":365,"rel":366},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@atlaskit\u002Fpragmatic-drag-and-drop-unit-testing",[345],"npm — @atlaskit\u002Fpragmatic-drag-and-drop-unit-testing",[114,369,370],{},[341,371,374],{"href":372,"rel":373},"https:\u002F\u002Fgithub.com\u002Fatlasstic-drag-and-drop",[345],"GitHub — atlassian\u002Fpragmatic-drag-and-drop",[114,376,377],{},[341,378,381],{"href":379,"rel":380},"https:\u002F\u002Fgithub.com\u002Ffrenicohansen\u002Fpdnd-vue",[345],"GitHub — frenicohansen\u002Fpdnd-vue (Vue 3 community example)",[114,383,384],{},[341,385,388],{"href":386,"rel":387},"https:\u002F\u002Fblog.logrocket.com\u002Fimplement-pragmatic-drag-drop-library-guide\u002F",[345],"LogRocket — \"Implement the Pragmatic drag and drop library\"",[114,390,391],{},[341,392,395],{"href":393,"rel":394},"https:\u002F\u002Fdrag-and-drop-performance-comparison.vercel.app\u002F",[345],"Drag and drop performance comparison",{"title":397,"searchDepth":398,"depth":398,"links":399},"",2,[400,401,402,403,404,405,406],{"id":26,"depth":398,"text":27},{"id":33,"depth":398,"text":34},{"id":73,"depth":398,"text":74},{"id":97,"depth":398,"text":98},{"id":161,"depth":398,"text":162},{"id":315,"depth":398,"text":316},{"id":334,"depth":398,"text":335},"2026-04-20","A comparison of SortableJS, FormKit DnD, and Atlassian's Pragmatic drag and drop — and why I landed on Pragmatic for a production kanban board.","md",{},true,"\u002Farticles\u002Fdrag-and-drop-vue3",{"title":5,"description":408},"articles\u002Fdrag-and-drop-vue3","UDrWZ1YqUNo42zDdU0dFaG-EMaX0Z6lrWUUT23PoKF0",1777543328114]