Remove All YouTube Liked Videos

Like Watch Later, YouTube's Liked videos playlist (internal ID LL) has no official "Unlike all" button — only per-video removal via each row's three-dot menu. This page documents a browser-console script that walks the Liked Videos playlist and unlikes every video automatically, with retry, stall-detection, and lazy-load handling built in for large libraries.



1. Why a Script Instead of Manual Removal

YouTube's help documentation for playlists covers removing a single video at a time: open the video's menu → Remove from Liked videos. For a library of any real size that is impractical by hand. The script below drives the identical UI action — it never touches a private API — just automatically and with the safety checks a manual pass would skip, like confirming each removal actually took effect before moving to the next row.


2. Console Script — Unlike All

Verified working. Run it with the Liked videos playlist open (youtube.com/playlist?list=LL) — the script checks the list=LL query parameter itself and refuses to run anywhere else.

(async () => {
  const playlistId = new URL(location.href).searchParams.get("list");

  if (playlistId !== "LL") {
    console.error("Open the YouTube Liked videos playlist first.");
    return;
  }

  if (window.__youtubeUnlikeAll?.running) {
    console.warn("The unlike script is already running.");
    return;
  }

  const state = {
    running: true,
    removed: 0,
    failures: 0
  };

  window.__youtubeUnlikeAll = state;

  window.stopUnlikeAll = () => {
    state.running = false;
    console.log("Stopping after the current video.");
  };

  const sleep = (milliseconds) =>
    new Promise((resolve) => setTimeout(resolve, milliseconds));

  const isDisplayed = (element) =>
    Boolean(
      element &&
      element.isConnected &&
      (element.offsetWidth ||
        element.offsetHeight ||
        element.getClientRects().length)
    );

  async function waitFor(test, timeout = 7000, interval = 100) {
    const start = Date.now();

    while (Date.now() - start < timeout) {
      const result = test();

      if (result) {
        return result;
      }

      await sleep(interval);
    }

    return null;
  }

  function getRows() {
    return [
      ...document.querySelectorAll("ytd-playlist-video-renderer")
    ].filter(isDisplayed);
  }

  function getVideoIdentity(row) {
    const link = row.querySelector(
      "a#video-title, a#thumbnail, a[href*='/watch']"
    );

    return link?.href || row.textContent?.trim() || "";
  }

  function closeOpenMenu() {
    const event = new KeyboardEvent("keydown", {
      key: "Escape",
      code: "Escape",
      keyCode: 27,
      which: 27,
      bubbles: true
    });

    document.activeElement?.dispatchEvent(event);
    document.dispatchEvent(event);
  }

  async function scrollToBottomAndLoad() {
    const beforeCount = getRows().length;
    const beforeHeight = document.documentElement.scrollHeight;

    window.scrollTo({
      top: document.documentElement.scrollHeight,
      behavior: "auto"
    });

    await sleep(1400);

    // A small upward/downward movement helps trigger YouTube's lazy loader.
    window.scrollBy({
      top: -300,
      behavior: "auto"
    });

    await sleep(200);

    window.scrollTo({
      top: document.documentElement.scrollHeight,
      behavior: "auto"
    });

    await sleep(1400);

    const afterCount = getRows().length;
    const afterHeight = document.documentElement.scrollHeight;

    return afterCount > beforeCount || afterHeight > beforeHeight;
  }

  async function removeLikedVideo(row) {
    if (!row?.isConnected) {
      return false;
    }

    const oldIdentity = getVideoIdentity(row);
    const oldRowCount = getRows().length;

    row.scrollIntoView({
      behavior: "auto",
      block: "center"
    });

    await sleep(350);

    const menuButton =
      row.querySelector("button[aria-label='Action menu']") ||
      row.querySelector("button[aria-label*='More actions']") ||
      row.querySelector("ytd-menu-renderer yt-icon-button button") ||
      row.querySelector("#menu yt-icon-button button") ||
      row.querySelector("#menu button");

    if (!menuButton) {
      console.warn("Could not find the three-dot menu.");
      return false;
    }

    menuButton.click();

    const removeOption = await waitFor(() => {
      const candidates = [
        ...document.querySelectorAll(
          [
            "ytd-popup-container ytd-menu-service-item-renderer",
            "tp-yt-iron-dropdown ytd-menu-service-item-renderer",
            "ytd-menu-service-item-renderer",
            "[role='menuitem']"
          ].join(",")
        )
      ].filter(isDisplayed);

      return candidates.find((item) =>
        /remove\s+from\s+liked\s+videos/i.test(
          item.innerText || item.textContent || ""
        )
      );
    });

    if (!removeOption) {
      closeOpenMenu();
      console.warn('Could not find "Remove from Liked videos."');
      return false;
    }

    removeOption.click();

    const removedSuccessfully = await waitFor(() => {
      if (!row.isConnected) {
        return true;
      }

      const newIdentity = getVideoIdentity(row);
      const newRowCount = getRows().length;

      return (
        newIdentity !== oldIdentity ||
        newRowCount < oldRowCount ||
        row.hasAttribute("is-dismissed")
      );
    }, 9000);

    if (!removedSuccessfully) {
      closeOpenMenu();
      console.warn("YouTube did not confirm removal. Retrying.");
      return false;
    }

    return true;
  }

  console.log(
    "Started removing liked videos. " +
    "To stop, enter: stopUnlikeAll()"
  );

  let emptyRounds = 0;

  while (state.running) {
    let rows = getRows();

    if (rows.length === 0) {
      const loadedMore = await scrollToBottomAndLoad();
      rows = getRows();

      if (rows.length === 0 && !loadedMore) {
        emptyRounds++;

        console.log(
          `Waiting for more videos: ${emptyRounds}/12`
        );

        if (emptyRounds >= 12) {
          break;
        }

        await sleep(1500);
        continue;
      }
    }

    emptyRounds = 0;

    // Process from the bottom so YouTube continues loading later pages.
    const row = rows[rows.length - 1];
    const success = await removeLikedVideo(row);

    if (success) {
      state.removed++;
      state.failures = 0;

      console.log(
        `Removed ${state.removed} liked video(s).`
      );

      await scrollToBottomAndLoad();

      // Occasional pause to reduce interface and rate-limit errors.
      if (state.removed % 25 === 0) {
        console.log("Pausing briefly...");
        await sleep(4000);
      } else {
        await sleep(700 + Math.random() * 500);
      }
    } else {
      state.failures++;

      console.warn(
        `Removal failure ${state.failures}/15. Retrying...`
      );

      closeOpenMenu();
      await scrollToBottomAndLoad();
      await sleep(1500);

      if (state.failures >= 15) {
        console.error(
          "Stopped after 15 consecutive failures. " +
          "Reload the page and run the script again."
        );
        break;
      }
    }
  }

  state.running = false;

  console.log(
    `Finished. Removed ${state.removed} liked video(s).`
  );
})();

3. How to Run It

  1. Open youtube.com/playlist?list=LL (your Liked videos playlist).
  2. Open the browser's developer console — Firefox: ⌘ + Option + K (Mac) or Ctrl + Shift + K (Windows/Linux); Chrome: ⌘ + Option + J (Mac) or Ctrl + Shift + J (Windows/Linux).
  3. If prompted, type allow pasting and press Enter before pasting the script.
  4. Paste the script and press Enter.
  5. Keep the tab open and in the foreground. Progress logs as Removed N liked video(s).; the run ends with Finished. Removed N liked video(s).

4. Runtime Controls & Console Output


5. Design Notes


6. Caveats