CodingCode ReviewIntermediate30 minSaves 30 minutes

React Drag-and-Drop Kanban Column with Optimistic UI

Frontend engineers building board UIs can generate a robust React Kanban column, featuring HTML5 DnD, optimistic updates, and API rollback for reliable user experiences.

Generate a React Kanban column component with native HTML5 drag-and-drop for reordering cards. This solution includes optimistic UI updates, API rollback on failure, and comprehensive tests to ensure a resilient and responsive user experience.

READY-TO-USE PROMPT

Copy Prompt

prompt.txt
As a Senior React Engineer, your objective is to architect and implement a production-ready Kanban column component.

### Context
I am developing a React application that requires a Kanban board interface. The core requirement is a column component that supports drag-and-drop reordering of cards within the column and handles updates to a backend API. This component must be robust, performant, and provide a smooth user experience even with network latency.

### Task
Develop a comprehensive React solution for a single Kanban column, enabling drag-and-drop reordering of cards. The implementation must include:
1.  **Component Structure:** A `KanbanColumn` component that renders a list of `KanbanCard` components.
2.  **Drag-and-Drop Logic:** Utilize native HTML5 Drag and Drop APIs for reordering cards.
    *   Cards should be draggable.
    *   The column should be a valid drop target for cards within itself.
    *   Provide visual feedback during drag operations (e.g., placeholder for dropped item, slight styling changes for draggable items).
3.  **State Management:** Manage the order of cards locally within the column.
4.  **Optimistic UI Updates:** Immediately update the UI to reflect the new card order upon a successful drag operation, *before* the API call returns.
5.  **API Integration:**
    *   After a drag-and-drop reorder, dispatch an asynchronous API request to `{{api_endpoint}}` to persist the new order.
    *   The API request should send the updated card IDs and their new order.
    *   On API success, maintain the optimistic update.
    *   On API failure, revert the UI to the state *before* the optimistic update (rollback).
6.  **Type Safety:** Implement all components, hooks, and data structures using TypeScript. Define interfaces for `KanbanCard` and `KanbanColumn` props. Assume a `{{card_data_structure}}` for card objects.
7.  **Accessibility (A11y):** Ensure the drag-and-drop functionality is accessible to keyboard users and screen readers. Include ARIA attributes where appropriate.
8.  **Performance:** Optimize for smooth animations and rendering, especially with many cards. Avoid unnecessary re-renders.
9.  **Testing:** Provide unit tests for the drag-and-drop logic, optimistic updates, and API interaction (including rollback). Use React Testing Library.

### Constraints
*   Use React functional components and hooks.
*   Avoid external drag-and-drop libraries; stick to native HTML5 DnD.
*   The solution should be modular, allowing the `KanbanColumn` to be easily integrated into a larger `KanbanBoard` component.
*   Assume the `KanbanCard` component is a simple presentational component, focusing the logic on the `KanbanColumn` and its associated hooks.
*   The API endpoint expects a PATCH or PUT request to update the order of cards.

### Output Format
Provide a complete, production-ready React solution, including:
1.  **File Tree:** A clear directory and file structure.
2.  **Full TSX Code:** For `KanbanColumn` component, `KanbanCard` (simple placeholder), and any custom hooks.
3.  **Custom Hooks:** Any necessary hooks for DnD logic, optimistic updates, or API calls.
4.  **Unit Tests:** Comprehensive tests covering the specified functionality.
5.  **Accessibility Notes:** A brief explanation of the a11y considerations and implemented features.
6.  **Performance Notes:** A brief explanation of performance considerations and implemented optimizations.

Estimated results

DifficultyIntermediate
Setup time30 min
Time saved30 minutes
Best modelsClaude, ChatGPT, Gemini
Best audienceSoftware Development, Project Management

Editor's note

Why this prompt matters

Building interactive user interfaces often involves complex state management, especially when integrating with backend services. A common challenge in applications featuring board-style layouts, like Kanban systems, is implementing reliable drag-and-drop functionality that feels responsive while maintaining data consistency. Engineers frequently encounter issues with visual glitches, race conditions, or incomplete data updates when trying to reconcile local UI changes with asynchronous API calls.

This workflow addresses these pain points by providing a structured approach to a React Kanban column. It focuses on using native HTML5 Drag and Drop APIs, which offer a lightweight alternative to external libraries, coupled with an optimistic UI update strategy. This combination ensures that users perceive immediate feedback, enhancing the overall experience, even under varying network conditions.

The solution is designed for React engineers who need to ship production-ready board UIs. It's particularly useful when a custom, performant, and accessible drag-and-drop list is required, where reliable backend synchronization and error handling are paramount. Reach for this pattern when building task managers, project boards, or any interface where items need to be reordered with immediate visual confirmation and robust data integrity.

Anatomy

Prompt engineering breakdown

Role

You are a Senior React Engineer.

Context

I need a React Kanban column with drag-and-drop card reordering. It must handle backend API updates with optimistic UI and rollback on failure. The component needs to be robust, performant, and provide a smooth user experience.

Goal

Develop a complete, production-ready React solution for a single Kanban column, including native HTML5 DnD, optimistic UI, API integration, TypeScript, accessibility, performance optimizations, and unit tests.

Constraints

Use React functional components and hooks, native HTML5 DnD only (no external libraries), ensure modularity, assume KanbanCard is presentational, and the API expects a PATCH/PUT for order updates.

Output format

A comprehensive output including a file tree, full TSX code (components, hooks), unit tests, accessibility notes, and performance notes.

Why this structure works

This structure ensures a high-quality, targeted response. Role priming as a 'Senior React Engineer' sets a clear expectation for code quality and architectural considerations. Explicit constraints like 'native HTML5 DnD' prevent off-topic solutions. Finally, the detailed output format ensures all necessary artifacts for a production-ready solution are provided, from code to documentation and tests.

Pick your version

Prompt variations

BeginnerBest with claude

For learning the fundamentals of React drag-and-drop and optimistic UI patterns, or for simple proof-of-concept implementations.

prompt.txt
As a React Developer, create a basic Kanban column component. This component should display a list of cards and allow users to reorder them within the column using native HTML5 drag and drop. Implement an optimistic UI update: when a card is dropped, immediately show the new order. After the drop, simulate an API call to `{{api_endpoint}}`. If the simulated API call fails, revert the cards to their original order. Use TypeScript for components and data structures, assuming a `{{card_data_structure}}` for cards. Focus on clear, readable code for the drag-and-drop and optimistic update logic. Provide the component's TSX code and any necessary hooks.
ProfessionalBest with chatgpt

When a comprehensive, production-grade solution is required, mirroring the original prompt's intent for a robust and well-tested component.

prompt.txt
Your task is to act as a Senior React Engineer and deliver a production-ready Kanban column component. The component must support drag-and-drop reordering of cards using native HTML5 DnD APIs, providing visual feedback during interactions. Implement local state management for card order. Crucially, apply optimistic UI updates: reflect changes instantly, then dispatch an asynchronous API request to `{{api_endpoint}}` to persist the new order. Handle API failures by reverting the UI to its prior state. The solution requires full TypeScript, including interfaces for `KanbanCard` and `KanbanColumn` props, based on a `{{card_data_structure}}`. Ensure accessibility for keyboard and screen readers, optimize for performance, and include unit tests using React Testing Library for DnD, optimistic updates, and API interaction with rollback. Output a file tree, all TSX code, custom hooks, tests, accessibility notes, and performance notes.
Short VersionBest with gemini

For experienced developers who need a quick, concise prompt to generate a functional solution without extensive detail.

prompt.txt
Generate a React Kanban column component. It needs native HTML5 drag-and-drop for card reordering, optimistic UI updates, and rollback on `{{api_endpoint}}` failure. Use TypeScript throughout, define `{{card_data_structure}}`, and provide an accessible, performant solution. Include component TSX, custom hooks, and unit tests for the DnD and API logic. Focus on a modular and production-ready implementation.
EnterpriseWorks with any model

For large-scale applications where security, compliance, data integrity, and stakeholder communication are critical considerations.

prompt.txt
As a Lead React Architect, design and implement a highly resilient Kanban column component for an enterprise application. This solution must incorporate native HTML5 Drag and Drop for card reordering with robust error handling and comprehensive optimistic UI. Upon reordering, the UI updates instantly, followed by a validated asynchronous call to `{{api_endpoint}}`. Implement a strict rollback mechanism on API failure, ensuring data integrity and user trust. The entire codebase must be in TypeScript, defining explicit interfaces for `KanbanCard` and `KanbanColumn` props, utilizing `{{card_data_structure}}`. Beyond core functionality, prioritize enterprise-grade concerns: full accessibility (WCAG 2.1 AA), extreme performance optimization for large datasets, and thorough security considerations to prevent XSS or data manipulation. Provide extensive unit and integration tests covering all critical paths, including edge cases and concurrency. Include detailed documentation for security implications, compliance (e.g., GDPR, HIPAA if applicable to data structure), and stakeholder review points, alongside performance and accessibility notes.

What you'll get

Expected output

kanban-column/ ├── src/ │ ├── components/ │ │ ├── KanbanColumn.tsx │ │ └── KanbanCard.tsx │ ├── hooks/ │ │ └── useOptimisticDragAndDrop.ts │ ├── api/ │ │ └── reorderCards.ts │ └── types.ts └── tests/ └── KanbanColumn.test.tsx

// src/hooks/useOptimisticDragAndDrop.ts (core logic excerpt) import { useState, useCallback, useRef } from 'react'; import { Card } from '../types'; import { reorderCards } from '../api/reorderCards'; // Mocked API call

export const useOptimisticDragAndDrop = (initialCards: Card[], apiEndpoint: string) => { const [cards, setCards] = useState<Card[]>(initialCards); const dragItem = useRef<number | null>(null); const originalCardsRef = useRef<Card[]>(initialCards); // Store for rollback

const handleDragStart = useCallback((e: React.DragEvent<HTMLDivElement>, position: number) => { dragItem.current = position; e.dataTransfer.effectAllowed = 'move'; }, []);

const handleDragEnter = useCallback((e: React.DragEvent<HTMLDivElement>, position: number) => { e.preventDefault(); if (dragItem.current === null || dragItem.current === position) return;

const newCards = [...cards]; const draggedCard = newCards[dragItem.current]; newCards.splice(dragItem.current, 1); newCards.splice(position, 0, draggedCard);

dragItem.current = position; // Update the 'current' position of the dragged item setCards(newCards); // Optimistic UI update }, [cards]);

const handleDragEnd = useCallback(async () => { if (dragItem.current === null) return;

const updatedOrder = cards.map(card => card.id); originalCardsRef.current = initialCards; // Snapshot initial state for rollback

try { await reorderCards(apiEndpoint, updatedOrder); // Simulate API call } catch (error) { console.error('Failed to reorder cards:', error); setCards(originalCardsRef.current); // Rollback on failure } finally { dragItem.current = null; } }, [cards, apiEndpoint, initialCards]);

return { cards, handleDragStart, handleDragEnter, handleDragEnd }; };

// Accessibility Notes

  • ARIA roles list and listitem provide semantic structure for screen readers.
  • aria-grabbed attribute on draggable cards communicates their drag state.
  • tabIndex={0} on cards allows keyboard focus and activation of drag-and-drop via Space/Enter keys, with arrow keys for navigation.
  • Visual focus indicators are implemented for keyboard users.

// Performance Notes

  • useCallback and useRef hooks are used to prevent unnecessary re-renders of components and memoize expensive computations.
  • Unique key props on list items ensure efficient DOM updates by React's reconciliation algorithm.
  • Optimistic UI updates provide immediate feedback, enhancing perceived performance and responsiveness, especially during network latency.
  • State management within the useOptimisticDragAndDrop hook is optimized to trigger minimal re-renders, impacting only the relevant parts of the UI.

Under the hood

Why this prompt works

This prompt structure significantly improves output quality compared to a simple request due to several deliberate prompt engineering techniques. First, role priming ("As a Senior React Engineer") establishes a high standard for the response, prompting the model to generate production-grade, idiomatic React code with a focus on best practices like type safety and performance.

Second, the detailed requirements and explicit constraints are crucial. Breaking the "Task" into nine specific points ensures comprehensive coverage of critical aspects such as native HTML5 DnD, optimistic UI, API rollback, accessibility, and testing. Explicitly forbidding external DnD libraries and requiring functional components guides the model to a specific, desired technical stack. This granularity prevents omissions often seen in less structured prompts, where non-functional requirements like accessibility or testing might be overlooked.

Finally, the structured output format ensures the generated solution is immediately usable and understandable. By demanding a file tree, full TSX code, custom hooks, and dedicated sections for tests, accessibility, and performance notes, the prompt forces the model to organize its output logically. This holistic approach yields a complete, well-documented, and ready-to-integrate solution, far exceeding the utility of a raw code dump.

Model fit

Best AI models for this prompt

Claude

Claude models handle the detailed interaction of optimistic UI, API rollback, and native HTML5 DnD with high accuracy. Its ability to generate comprehensive TypeScript interfaces and structured code makes it suitable for complex frontend logic. However, always review the generated accessibility attributes for adherence to specific WCAG guidelines. See the full Claude hub for deeper guidance.

ChatGPT

ChatGPT is effective for generating the foundational React component structure and integrating basic drag-and-drop mechanics. It can produce functional code for the optimistic update pattern and API calls, but the user should thoroughly validate the implementation details for edge cases and ensure the native HTML5 DnD API usage is robust. See the full ChatGPT hub for deeper guidance.

Gemini

Gemini can generate a functional starting point for the Kanban column, including the basic drag-and-drop and state management. While it can draft the optimistic update logic, ensure to verify the rollback mechanism and the finer points of accessibility. Its output often provides a good base that can be refined with specific performance considerations. See the full Gemini hub for deeper guidance.

When to use

  • When building a Kanban board or similar reorderable list within a single container.
  • When native HTML5 Drag and Drop is the chosen strategy to avoid external library dependencies.
  • When optimistic UI updates are critical for perceived performance, especially with network latency.
  • When robust backend API integration, including UI rollback on failure, is required for data persistence.
  • When a type-safe, testable, and maintainable solution is a priority for a React component.

When not to use

  • For highly complex drag-and-drop interactions beyond simple reordering within one list.
  • When cross-column or cross-list dragging is a primary requirement without significant architectural changes.
  • If broad browser support for very old HTML5 DnD implementations is a strict constraint.
  • When an existing, opinionated drag-and-drop library is already standardized across the project.
  • For purely static lists where reordering is not an interactive feature.

Get more from it

Pro tips

  • 1

    Ensure `dataTransfer.setData` is correctly called on `dragstart` with a unique card ID to prevent issues with dropped item identification.

  • 2

    Implement a clear visual placeholder for the dragged item's potential drop position to provide better user feedback during the interaction.

  • 3

    Thoroughly test the API rollback mechanism by simulating network failures; this prevents data inconsistencies and user frustration.

  • 4

    Utilize `useCallback` and `useMemo` for event handlers and component children to prevent unnecessary re-renders, improving performance with many cards.

  • 5

    Pay close attention to `aria-grabbed`, `aria-dropeffect`, and keyboard navigation to ensure the solution meets accessibility standards for all users.

  • 6

    Abstract the API interaction into a dedicated custom hook; this keeps component logic clean and simplifies testing of API success and failure paths.

  • 7

    Consider debouncing or throttling API calls if rapid, successive reorders are common, reducing unnecessary server load from frequent updates.

Don't ship this

Common mistakes

  • Forgetting to set `draggable="true"` on the individual card components.

    Fix — Cards will not initiate drag events. Ensure the `draggable` attribute is explicitly set on the elements meant to be dragged.

  • Not calling `event.preventDefault()` within the `dragover` event handler on the drop target.

    Fix — The `drop` event will not fire, as the browser's default behavior typically prevents dropping in most scenarios. Always prevent default.

  • Implementing optimistic UI without a clear rollback strategy for API failures.

    Fix — Build a robust state restoration path for API failures to prevent the UI from displaying incorrect or unsynced data to the user.

  • Insufficient keyboard accessibility for drag-and-drop functionality.

    Fix — Provide keyboard equivalents using `onKeyDown` handlers for reordering and include relevant ARIA attributes like `aria-grabbed`.

  • Performance degradation with many cards due to excessive component re-renders.

    Fix — Memoize `KanbanCard` components and event handlers to ensure only changed items or necessary re-renders occur.

  • The `dataTransfer` object being empty or incorrectly populated during drag and drop.

    Fix — Verify that `event.dataTransfer.setData` is called on `dragstart` and `event.dataTransfer.getData` on `drop` with matching data types.

People also ask

Frequently asked questions

Q.Can this solution be extended to drag cards between different columns?

Yes, but it requires significant modification. The current implementation focuses on intra-column reordering. Inter-column dragging involves managing state across multiple KanbanColumn instances and coordinating global drop targets.

Q.How do I handle very large numbers of cards, for example, hundreds or thousands?

For large card counts, consider implementing list virtualization. Libraries like React Window or React Virtualized render only the visible items, drastically improving performance beyond standard rendering approaches.

Q.Is native HTML5 Drag and Drop truly sufficient for complex scenarios?

For basic reordering and simple drop targets, native HTML5 DnD works well. For more intricate interactions like multiple drag handles or highly customized visual feedback, a dedicated drag-and-drop library might offer more features out-of-the-box.

Q.How can I visually indicate the exact position where a card will drop?

Implement a 'drop indicator' element, often a thin line or box, that appears dynamically when a draggable item hovers over a potential drop zone, showing the precise insertion point. This enhances user clarity.

Q.What if the backend API is very slow or frequently returns errors?

The optimistic UI handles these cases by providing immediate user feedback and rolling back on API failure. For persistent slowness, consider adding a temporary loading indicator on individual cards or the column while the API call is pending.

Q.Does this solution support mobile touch dragging and dropping?

Native HTML5 Drag and Drop has inconsistent or limited touch support across various mobile browsers and devices. For a robust mobile experience, a separate touch-specific library or custom touch event handling is generally required.

Version 1.0Last reviewed July 20, 2026
Reviewed by PromptInFlow Editorial Team