[{"data":1,"prerenderedAt":481},["ShallowReactive",2],{"articles-list":3},[4,417],{"id":5,"title":6,"body":7,"date":408,"description":409,"extension":410,"meta":411,"navigation":412,"path":413,"seo":414,"stem":415,"__hash__":416},"articles\u002Farticles\u002Fdrag-and-drop-vue3.md","Picking a Drag and Drop Library for Vue 3",{"type":8,"value":9,"toc":397},"minimark",[10,14,17,24,29,32,36,48,59,69,72,76,79,88,93,96,100,107,111,142,146,160,164,314,318,321,330,333,337],[11,12,13],"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.",[11,15,16],{},"Here's what I found after evaluating the three main options.",[11,18,19],{},[20,21],"img",{"alt":22,"src":23},"Pragmatic drag and drop in action — cards being dragged across Confluence, Jira, and Trello columns","\u002Farticles\u002Fpragmatic-dnd-demo.png",[25,26,28],"h2",{"id":27},"the-use-case","The use case",[11,30,31],{},"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.",[25,33,35],{"id":34},"sortablejs-vuedraggable","SortableJS \u002F vuedraggable",[11,37,38,39,43,44,47],{},"The default answer in the Vue ecosystem. ",[40,41,42],"code",{},"vuedraggable"," is a Vue wrapper around SortableJS with a component-based API and ",[40,45,46],{},"v-model"," integration for cross-list dragging.",[11,49,50,54,55,58],{},[51,52,53],"strong",{},"Strengths:"," Simple declarative API. The ",[40,56,57],{},"group"," prop makes cross-list dragging almost trivial. Built-in animation with a single prop. Large community with lots of real-world examples.",[11,60,61,64,65,68],{},[51,62,63],{},"Weaknesses:"," The Vue 3 version (",[40,66,67],{},"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.",[11,70,71],{},"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.",[25,73,75],{"id":74},"formkit-drag-and-drop","FormKit drag and drop",[11,77,78],{},"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.",[11,80,81,83,84,87],{},[51,82,53],{}," The ",[40,85,86],{},"useDragAndDrop"," composable feels native in a Vue 3 codebase. Lightweight core. Actively developed.",[11,89,90,92],{},[51,91,63],{}," 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.",[11,94,95],{},"Promising direction, but too early to bet on in a production context.",[25,97,99],{"id":98},"pragmatic-drag-and-drop-atlassian","Pragmatic drag and drop (Atlassian)",[11,101,102,103,106],{},"Atlassian's current drag and drop framework — the successor to ",[40,104,105],{},"react-beautiful-dnd",", and what powers Trello, Jira, and Confluence today. Headless, framework-agnostic, built on the native HTML5 drag and drop API.",[11,108,109],{},[51,110,53],{},[112,113,114,118,121,124,127,130,133,136],"ul",{},[115,116,117],"li",{},"Tiny core (~4.7KB) with optional add-ons loaded on demand",[115,119,120],{},"Fully framework-agnostic — works with Vue, React, Svelte, Angular, or vanilla JS",[115,122,123],{},"Native HTML5 API means cross-window dragging and external file drops work out of the box",[115,125,126],{},"Deferred loading compatible, so it doesn't affect initial page load",[115,128,129],{},"Battle-tested at Trello and Jira scale",[115,131,132],{},"Headless: no visual opinions, full control over feedback and animation",[115,134,135],{},"Automatic DOM reconciliation when elements are destroyed and recreated by the framework",[115,137,138,141],{},[40,139,140],{},"@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.",[11,143,144],{},[51,145,63],{},[112,147,148,154,157],{},[115,149,150,151,153],{},"Lower-level API means more setup than ",[40,152,42],{},"'s declarative approach",[115,155,156],{},"Documentation is React-centric; Vue examples are community-contributed",[115,158,159],{},"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",[25,161,163],{"id":162},"comparison","Comparison",[165,166,167,186],"table",{},[168,169,170],"thead",{},[171,172,173,177,180,183],"tr",{},[174,175,176],"th",{},"Criteria",[174,178,179],{},"SortableJS",[174,181,182],{},"FormKit DnD",[174,184,185],{},"Pragmatic DnD",[187,188,189,204,218,230,241,252,263,277,291,302],"tbody",{},[171,190,191,195,198,201],{},[192,193,194],"td",{},"Vue 3 support",[192,196,197],{},"Wrapper",[192,199,200],{},"Yes",[192,202,203],{},"Yes (native)",[171,205,206,209,212,215],{},[192,207,208],{},"Bundle (core)",[192,210,211],{},"~12KB",[192,213,214],{},"~5KB",[192,216,217],{},"~4.7KB",[171,219,220,223,226,228],{},[192,221,222],{},"Native HTML5 API",[192,224,225],{},"No",[192,227,225],{},[192,229,200],{},[171,231,232,235,237,239],{},[192,233,234],{},"Cross-window drag",[192,236,225],{},[192,238,225],{},[192,240,200],{},[171,242,243,246,248,250],{},[192,244,245],{},"File drop support",[192,247,225],{},[192,249,225],{},[192,251,200],{},[171,253,254,257,259,261],{},[192,255,256],{},"Deferred loading",[192,258,225],{},[192,260,225],{},[192,262,200],{},[171,264,265,268,271,274],{},[192,266,267],{},"Production scale",[192,269,270],{},"Medium",[192,272,273],{},"Early stage",[192,275,276],{},"Trello, Jira",[171,278,279,282,285,288],{},[192,280,281],{},"Maintenance",[192,283,284],{},"Low activity",[192,286,287],{},"Active (pre-1.0)",[192,289,290],{},"Active (Atlassian)",[171,292,293,296,298,300],{},[192,294,295],{},"Unit testing package",[192,297,225],{},[192,299,225],{},[192,301,200],{},[171,303,304,307,310,312],{},[192,305,306],{},"Setup complexity",[192,308,309],{},"Low",[192,311,309],{},[192,313,270],{},[25,315,317],{"id":316},"what-i-chose-and-why","What I chose, and why",[11,319,320],{},"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.",[11,322,323,324,326,327,329],{},"The setup cost is real compared to ",[40,325,42],{},". There is no ",[40,328,46],{}," 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.",[11,331,332],{},"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.",[25,334,336],{"id":335},"references","References",[112,338,339,348,355,362,369,376,383,390],{},[115,340,341],{},[342,343,347],"a",{"href":344,"rel":345},"https:\u002F\u002Fatlassian.design\u002Fcomponents\u002Fpragmatic-drag-and-drop",[346],"nofollow","Atlassian — Pragmatic drag and drop documentation",[115,349,350],{},[342,351,354],{"href":352,"rel":353},"https:\u002F\u002Fwww.atlassian.com\u002Fblog\u002Fdesign\u002Fdesigned-for-delight-built-for-performance",[346],"Atlassian Blog — \"Designed for delight, built for performance\"",[115,356,357],{},[342,358,361],{"href":359,"rel":360},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@atlaskit\u002Fpragmatic-drag-and-drop",[346],"npm — @atlaskit\u002Fpragmatic-drag-and-drop",[115,363,364],{},[342,365,368],{"href":366,"rel":367},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@atlaskit\u002Fpragmatic-drag-and-drop-unit-testing",[346],"npm — @atlaskit\u002Fpragmatic-drag-and-drop-unit-testing",[115,370,371],{},[342,372,375],{"href":373,"rel":374},"https:\u002F\u002Fgithub.com\u002Fatlasstic-drag-and-drop",[346],"GitHub — atlassian\u002Fpragmatic-drag-and-drop",[115,377,378],{},[342,379,382],{"href":380,"rel":381},"https:\u002F\u002Fgithub.com\u002Ffrenicohansen\u002Fpdnd-vue",[346],"GitHub — frenicohansen\u002Fpdnd-vue (Vue 3 community example)",[115,384,385],{},[342,386,389],{"href":387,"rel":388},"https:\u002F\u002Fblog.logrocket.com\u002Fimplement-pragmatic-drag-drop-library-guide\u002F",[346],"LogRocket — \"Implement the Pragmatic drag and drop library\"",[115,391,392],{},[342,393,396],{"href":394,"rel":395},"https:\u002F\u002Fdrag-and-drop-performance-comparison.vercel.app\u002F",[346],"Drag and drop performance comparison",{"title":398,"searchDepth":399,"depth":399,"links":400},"",2,[401,402,403,404,405,406,407],{"id":27,"depth":399,"text":28},{"id":34,"depth":399,"text":35},{"id":74,"depth":399,"text":75},{"id":98,"depth":399,"text":99},{"id":162,"depth":399,"text":163},{"id":316,"depth":399,"text":317},{"id":335,"depth":399,"text":336},"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":6,"description":409},"articles\u002Fdrag-and-drop-vue3","UDrWZ1YqUNo42zDdU0dFaG-EMaX0Z6lrWUUT23PoKF0",{"id":418,"title":419,"body":420,"date":474,"description":475,"extension":410,"meta":476,"navigation":412,"path":477,"seo":478,"stem":479,"__hash__":480},"articles\u002Farticles\u002Ffrom-stage-to-code.md","From the stage to the code editor",{"type":8,"value":421,"toc":469},[422,425,428,431,435,438,441,445,448,451,455,458,461,463,466],[11,423,424],{},"Before writing a single line of code, I spent years working in festivals and tours. Technical production: one more cog in a machine where a hundred people who don't know each other have to execute the same plan at the same time, without the audience noticing a thing.",[11,426,427],{},"When I got into development I thought I'd have to learn everything from scratch. And partly, yes. But what surprised me most was discovering that the hardest part of the job — which isn't the technical part — I already knew.",[429,430],"hr",{},[25,432,434],{"id":433},"talking-to-people-who-know-things-you-dont","Talking to people who know things you don't",[11,436,437],{},"In production you're one specialist among specialists. The sound engineer knows more about audio than you. The lighting tech knows more about lights. Nobody expects you to know everything, but they do expect you to understand enough about each area to do your part well and not get in everyone else's way.",[11,439,440],{},"In a development team it's the same. Product understands the user and decides what to build. Infrastructure knows the real limits of the system. Design knows what makes visual sense. Your job as a dev is to do your part well within that context: write code that reflects what everyone agreed on together. If you don't listen well, you end up building the wrong thing perfectly.",[25,442,444],{"id":443},"trust-as-infrastructure","Trust as infrastructure",[11,446,447],{},"At a festival, the event works because each person trusts that everyone else will do their part. Not because someone controls everything, but because the goal is clear enough for each person to make good decisions within their own area.",[11,449,450],{},"Development is no different. A team that works well — product, infra, dev — doesn't need anyone hovering over everything. It needs everyone to understand where they're going and move in that direction.",[25,452,454],{"id":453},"the-real-problems-show-up-live","The real problems show up live",[11,456,457],{},"No matter how much you plan, the dress rehearsal is never like the actual show. What you learn after enough unexpected problems isn't how to avoid them, but how to stay calm when they happen and communicate clearly in the middle of the chaos.",[11,459,460],{},"In development that means fixing a critical bug in production or pushing through a last-minute change before a release. The situation is different. The pressure and the skills you need are exactly the same.",[429,462],{},[11,464,465],{},"I changed industries, but I didn't entirely change jobs. I'm still a technician inside a team, still managing uncertainty, still trying to make something complex look simple from the outside.",[11,467,468],{},"The difference is that now problems get solved over Slack instead of through an earpiece. And I can stay home when it rains.",{"title":398,"searchDepth":399,"depth":399,"links":470},[471,472,473],{"id":433,"depth":399,"text":434},{"id":443,"depth":399,"text":444},{"id":453,"depth":399,"text":454},"2026-04-16","Before writing a single line of code, I spent years working in festivals and tours. What I didn't expect was how much of the job I already knew.",{},"\u002Farticles\u002Ffrom-stage-to-code",{"title":419,"description":475},"articles\u002Ffrom-stage-to-code","aud_UWldvhyltPKBPCZoOP9fSHXO878Hp7aoghMA7XI",1777543328034]