Guides
Retool Table Drag and Drop: How to Reorder Rows
If you've been trying to add Retool table drag and drop row reordering to your internal tool, you've probably already hit the wall: the Table component doesn't support it natively. This has been one of the most upvoted open feature requests in the Retool community since at least 2022, and as of now, the engineering team hasn't shipped it. But there are real, working workarounds — and this post walks through each one so you can ship your feature today.
Why Retool Tables Don't Support Drag and Drop Reordering
The Table component in Retool is optimized for displaying and editing structured data — sorting, filtering, pagination, inline editing, action buttons. Row reordering via drag and drop is a fundamentally different interaction pattern that introduces tricky state management questions: Where does the new order get persisted? How does it interact with server-side sorting? What happens when you paginate?
These aren't impossible problems, but they explain why Retool's team has repeatedly acknowledged the request without prioritizing it. Their current official recommendation is to use a Custom Component or the built-in Reorderable List component as a stopgap.
Workaround 1: Use the Reorderable List Component
Retool ships a Reorderable List component that does exactly what it sounds like — users can drag and drop items to reorder them. It's the fastest path to drag-and-drop ordering if your use case is simple.
How to set it up:
- Drag a
Reorderable Listcomponent onto your canvas. - Set its Data property to the same query or transformer that feeds your table — for example,
{{ getProjectTasks.data }}. - Use the Item Template field to customize what each row displays using HTML — you can render task names, dates, status badges, etc.
- Read the reordered output from
{{ reorderableList1.value }}and use it to drive a subsequentUPDATEorPATCHquery that persists the new order to your database.
Limitations to know upfront:
- You cannot add action buttons (like Edit or Delete) to individual list items — there's no click handler on list rows.
- Styling control is limited. You can customize the HTML template per item, but the list container itself has very little style flexibility, making it harder to match your app's design.
- It's not a table — if your users expect a grid layout with column headers, this will feel off.
Workaround 2: Split the UI — Table for Editing, List for Ordering
This is the most pragmatic pattern used by teams who need both inline editing and manual ordering. The idea is to keep these two interactions separate rather than cramming them into one component.
- Use the
Tablecomponent as your primary editing surface — inline edits, action button columns for Delete/Edit, all the standard table features. - Add a separate Reorder button on the page that opens a
Modal. - Inside the modal, place a
Reorderable Listthat lets users drag rows into the order they want. - On modal save, write the new sort order back to your data source (e.g., update an
orderorpositioninteger column in your database). - Trigger a refresh of your main table query so the updated order is reflected immediately.
This isn't seamless UX, but it's reliable, buildable in under an hour, and keeps your data model clean.
Workaround 3: Add an Order Column with Manual Input
The lowest-tech approach — and sometimes the most honest one. Add an order integer column to your database table and expose it as an editable column in your Table component. Users type in a number to set priority or sequence, and you sort the table by that column.
- Enable inline editing on the
ordercolumn in yourTablecomponent settings. - Set the table's default Sort Column to
order, ascending. - Wire the table's
onSaveevent to anUPDATEquery that persists the changed value.
It's not drag and drop, but for power users managing show schedules, project milestones, or priority queues, typing a number is often faster than dragging anyway.
Workaround 4: Build a Custom Component
If none of the above fits your requirements, Retool's official recommendation is to use a Custom Component. You can embed any JavaScript-based drag-and-drop library — SortableJS is the most popular choice — inside a custom component iframe, render your table data inside it, and emit the reordered array back to Retool via Retool.modelUpdate.
This gives you full control over appearance and behavior, but it comes with real costs: you're now maintaining a small frontend codebase inside your Retool app, debugging across the iframe boundary is painful, and onboarding other builders on your team gets harder.
Reserve this approach for cases where the UX requirement is non-negotiable and the simpler workarounds genuinely don't cut it.
Which Workaround Should You Use?
- Simple list ordering, no editing needed: Use the
Reorderable Listcomponent directly. - Need both editing and ordering: Use the Table + Modal + Reorderable List split pattern.
- Power users who don't mind typing: Add an
ordercolumn with inline editing. - Pixel-perfect UX is a hard requirement: Build a
Custom Componentwith SortableJS.
Tracking the Native Feature Request
The Retool team is aware of this gap and is tracking demand internally. If you want native Table drag-and-drop row reordering to get prioritized, the best thing you can do is add your voice to the official community thread. Enough upvotes and real use case descriptions do move the needle on roadmap prioritization.
Until then, the workarounds above cover the vast majority of real-world use cases. Pick the one that matches your constraints and ship it.
Ready to build?
We scope, design, and ship your Retool app — fast.