Skip to content

Instantly share code, notes, and snippets.

@rhmnaulia
Created March 23, 2025 08:04
Show Gist options
  • Save rhmnaulia/a43df442730b0f5d28066e3ea08ff3ac to your computer and use it in GitHub Desktop.
Save rhmnaulia/a43df442730b0f5d28066e3ea08ff3ac to your computer and use it in GitHub Desktop.
/**
* X/Twitter Bookmark Remover
*
* This script automatically removes all bookmarks from your X/Twitter account
* by scrolling through your bookmarks page and clicking the remove button for each bookmark.
*
* HOW TO USE:
* 1. Go to your bookmarks page: https://twitter.com/i/bookmarks or https://x.com/i/bookmarks
* 2. Open browser developer console (F12 or Ctrl+Shift+J or Cmd+Option+J)
* 3. Copy and paste this entire script into the console
* 4. Press Enter to run
*/
(async function() {
// Configuration - Feel free to adjust these values
const scrollDelay = 800; // Time to wait between scrolls (ms)
const removeDelay = 500; // Time to wait after clicking remove button (ms)
const maxScrollAttempts = 200; // Maximum number of scroll attempts
const loggingEnabled = true; // Enable console logging
// Helper function for logging
const log = (message) => {
if (loggingEnabled) {
console.log(`%c[Bookmark Remover] ${message}`, 'color: #1DA1F2; font-weight: bold;');
}
};
// Helper function to wait
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// Check if we're on the bookmarks page
if (!window.location.href.includes('/bookmarks')) {
log('Please navigate to your bookmarks page (https://twitter.com/i/bookmarks or https://x.com/i/bookmarks)');
return;
}
log('Starting bookmark removal process...');
// Track metrics
let removedCount = 0;
let failedAttempts = 0;
let consecutiveNoNewButtons = 0;
let lastButtonCount = 0;
// Main function to remove all bookmarks
async function removeAllBookmarks() {
try {
let scrollAttempts = 0;
while (scrollAttempts < maxScrollAttempts) {
// Find all bookmark remove buttons
// For X/Twitter, the bookmark remove buttons have data-testid="removeBookmark"
const removeButtons = document.querySelectorAll('button[data-testid="removeBookmark"]');
// If no buttons found and we've scrolled a lot, we might be done
if (removeButtons.length === 0) {
log('No bookmark buttons found. Scrolling to load more...');
window.scrollTo(0, document.body.scrollHeight);
await wait(scrollDelay);
scrollAttempts++;
consecutiveNoNewButtons++;
// If we've had many attempts with no new buttons, assume we're done
if (consecutiveNoNewButtons > 10) {
log('No new bookmarks found after multiple scroll attempts. Assuming all bookmarks are removed.');
break;
}
continue;
}
// Reset consecutive counter if we found buttons
if (removeButtons.length > lastButtonCount) {
consecutiveNoNewButtons = 0;
}
lastButtonCount = removeButtons.length;
log(`Found ${removeButtons.length} bookmark buttons. Removing...`);
// Click each remove button
let removedAny = false;
for (const button of removeButtons) {
try {
if (button && button.isConnected) {
// Scroll the button into view
button.scrollIntoView({ behavior: 'smooth', block: 'center' });
await wait(300); // Small wait to let scroll finish
// Click the button
button.click();
removedCount++;
removedAny = true;
// Log progress periodically
if (removedCount % 10 === 0) {
log(`Removed ${removedCount} bookmarks so far...`);
}
// Wait a bit after each removal to let the UI update
await wait(removeDelay);
}
} catch (err) {
failedAttempts++;
log(`Failed to remove a bookmark: ${err.message}`);
}
}
// If we didn't remove any bookmarks in this pass, scroll down to load more
if (!removedAny) {
window.scrollTo(0, document.body.scrollHeight);
await wait(scrollDelay);
scrollAttempts++;
}
}
log(`Bookmark removal completed! Successfully removed ${removedCount} bookmarks with ${failedAttempts} failed attempts.`);
if (scrollAttempts >= maxScrollAttempts) {
log('Reached maximum scroll attempts. Some bookmarks may remain.');
}
} catch (error) {
log(`An error occurred: ${error.message}`);
}
}
// Start the removal process
await removeAllBookmarks();
})();
@culeric
Copy link

culeric commented Apr 26, 2025

you are the best man , thank you for the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment