Frontend

Draggable Notes List (Google Frontend Interview) | Frontend System Design

A common frontend system design question asked at Google focuses on building a draggable list of notes. Users should be able to reorder items via drag-and-drop and have the updated order persist across sessions. This tests your understanding of DOM interactions, state management, event handling, and client-side persistence in real-world UI systems.

ByteAndBites·Jul 16, 2026
Draggable Notes List (Google Frontend Interview) | Frontend System Design

This is a frontend system design problem commonly asked at Google where the goal is to build a draggable list of notes. Users should be able to reorder items using drag-and-drop, and the updated order should persist even after refreshing the page. The focus is entirely on frontend behavior, handling user interactions, managing state, and ensuring persistence.


Concepts
The problem touches multiple core frontend concepts.

Problem Breakdown

We start with a simple list of notes, for example an array of strings or objects. Each item should be rendered as a draggable element.

The core challenge is detecting how the order changes when a user drags one item and drops it at another position. This means we need to track:

Another part is ensuring that the updated order is saved so that when the page reloads, the list remains the same. This introduces persistence logic.

So the problem can be broken into:

  1. Render list

  2. Enable dragging

  3. Detect drop position

  4. Reorder array

  5. Persist updated list

Sample Draggable List
Sample Draggable List


Solution
We can implement this using basic HTML drag events.

Each list item is marked as draggable. When dragging starts, we store the index of the dragged item. When dragging over another item, we prevent default behavior to allow dropping. On drop, we reorder the list.


Here is a simple implementation:

HTML(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Draggable Notes</title>
  <link rel="stylesheet" href="./index.css" />
</head>
<body>

  <div class="container">
    <h2>Draggable Notes</h2>
    <div id="list" class="list"></div>
  </div>

  <script src="./draggable.js"></script>
</body>
</html>

CSS(index.css)
body {
    font-family: Arial, sans-serif;
    background: #f4f6f8;
    display: flex;
    justify-content: center;
    margin-top: 60px;
  }
  
  .container {
    width: 320px;
  }
  
  h2 {
    text-align: center;
    margin-bottom: 20px;
  }
  
  .list {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  
  .item {
    background: white;
    padding: 14px;
    border-radius: 8px;
    cursor: grab;
    border: 1px solid #e0e0e0;
    transition: all 0.2s ease;
  }
  
  .item:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  }
  
  .item:active {
    cursor: grabbing;
    transform: scale(1.02);
  }
  
  .dragging {
    opacity: 0.5;
  }

JavaScript(draggable.js)
const listEl = document.getElementById("list");

let notes = JSON.parse(localStorage.getItem("notes")) || [
  "Learn Drag and Drop",
  "Prepare for Interview",
  "Build UI Projects",
  "Revise JavaScript"
];

let dragIndex = null;

function render() {
  listEl.innerHTML = "";

  notes.forEach((note, index) => {
    const item = document.createElement("div");
    item.className = "item";
    item.innerText = note;
    item.draggable = true;

    item.addEventListener("dragstart", () => {
      dragIndex = index;
      item.classList.add("dragging");
    });

    item.addEventListener("dragend", () => {
      item.classList.remove("dragging");
    });

    item.addEventListener("dragover", (e) => {
      e.preventDefault();
    });

    item.addEventListener("drop", () => {
      const draggedItem = notes[dragIndex];

      notes.splice(dragIndex, 1);
      notes.splice(index, 0, draggedItem);

      localStorage.setItem("notes", JSON.stringify(notes));
      render();
    });

    listEl.appendChild(item);
  });
}

render();


Explanation of the logic:


Conclusion

This problem is less about complex algorithms and more about handling user interaction cleanly. The key is to think in terms of state changes rather than DOM manipulation. Once you model the list as an array, reordering becomes straightforward. Persistence is a small addition but shows production thinking. Interviewers are looking for clarity in approach, not perfection in UI.


Similar Questions

InterviewGoogleHTMLUIJira BoardJavascriptArraySystem Design
Frontend Interview Playbook 🚀
Series
Frontend Interview Playbook 🚀
View series
A curated series of real frontend interview questions from top companies like Google, Amazon, Uber, Atlassian, Roku, etc. Each blog breaks down problems, thought processes, and optimal solutions to help you master concepts, improve problem-solving, and confidently crack frontend interviews at leading tech companies.