๐ Unfollow Tutorials
Complete guides for mass unfollowing on X/Twitter
๐ 1. Unfollow Everyone
๐ What This Does
Mass unfollows ALL accounts you're currently following. This is the nuclear option - use it when you want to start fresh with a clean following list.
๐ฏ Quick Start
- Go to
x.com/YOUR_USERNAME/following - Open DevTools with
F12(Windows/Linux) orCmd+Option+J(Mac) - Click the "Console" tab
- Paste the code below and press Enter
// Unfollow everyone on X
// by nichxbt - https://github.com/nirholas/XActions
(() => {
const $followButtons = '[data-testid$="-unfollow"]';
const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
const retry = {
count: 0,
limit: 3,
};
const scrollToTheBottom = () => window.scrollTo(0, document.body.scrollHeight);
const retryLimitReached = () => retry.count === retry.limit;
const addNewRetry = () => retry.count++;
const sleep = ({ seconds }) =>
new Promise((proceed) => {
console.log(`WAITING FOR ${seconds} SECONDS...`);
setTimeout(proceed, seconds * 1000);
});
const unfollowAll = async (followButtons) => {
console.log(`UNFOLLOWING ${followButtons.length} USERS...`);
await Promise.all(
followButtons.map(async (followButton) => {
followButton && followButton.click();
await sleep({ seconds: 1 });
const confirmButton = document.querySelector($confirmButton);
confirmButton && confirmButton.click();
})
);
};
const nextBatch = async () => {
scrollToTheBottom();
await sleep({ seconds: 1 });
const followButtons = Array.from(document.querySelectorAll($followButtons));
const followButtonsWereFound = followButtons.length > 0;
if (followButtonsWereFound) {
await unfollowAll(followButtons);
await sleep({ seconds: 2 });
return nextBatch();
} else {
addNewRetry();
}
if (retryLimitReached()) {
console.log(`NO ACCOUNTS FOUND, SO I THINK WE'RE DONE`);
console.log(`RELOAD PAGE AND RE-RUN SCRIPT IF ANY WERE MISSED`);
} else {
await sleep({ seconds: 2 });
return nextBatch();
}
};
nextBatch();
})();
This will unfollow EVERYONE. There's no undo button. Make sure you really want to do this!
โ๏ธ How It Works
- Scrolls down your following list to load more accounts
- Finds all "Following" buttons and clicks them
- Automatically confirms each unfollow
- Repeats until no more accounts are found
- Retries 3 times to catch any stragglers
๐ฅ 2. Unfollow Non-Followers Only
๐ What This Does
Unfollows only people who don't follow you back. Keeps mutual follows intact. Perfect for cleaning up your following list without losing your real connections.
๐ฏ Quick Start
- Go to
x.com/YOUR_USERNAME/following - Open DevTools (F12 or Cmd+Option+J)
- Paste the code below and press Enter
// Unfollow people who don't follow you back
// by nichxbt - https://github.com/nirholas/XActions
(() => {
const $followButtons = '[data-testid$="-unfollow"]';
const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
const retry = {
count: 0,
limit: 3,
};
const scrollToTheBottom = () => window.scrollTo(0, document.body.scrollHeight);
const retryLimitReached = () => retry.count === retry.limit;
const addNewRetry = () => retry.count++;
const sleep = ({ seconds }) =>
new Promise((proceed) => {
console.log(`WAITING FOR ${seconds} SECONDS...`);
setTimeout(proceed, seconds * 1000);
});
const unfollowAll = async (followButtons) => {
console.log(`UNFOLLOWING ${followButtons.length} USERS...`);
await Promise.all(
followButtons.map(async (followButton) => {
followButton && followButton.click();
await sleep({ seconds: 1 });
const confirmButton = document.querySelector($confirmButton);
confirmButton && confirmButton.click();
})
);
};
const nextBatch = async () => {
scrollToTheBottom();
await sleep({ seconds: 1 });
let followButtons = Array.from(document.querySelectorAll($followButtons));
// Filter out users who follow you back (they have the "Follows you" indicator)
followButtons = followButtons.filter(b =>
b.parentElement?.parentElement?.querySelector('[data-testid="userFollowIndicator"]') === null
);
const followButtonsWereFound = followButtons.length > 0;
if (followButtonsWereFound) {
await unfollowAll(followButtons);
await sleep({ seconds: 2 });
return nextBatch();
} else {
addNewRetry();
}
if (retryLimitReached()) {
console.log(`NO ACCOUNTS FOUND, SO I THINK WE'RE DONE`);
console.log(`RELOAD PAGE AND RE-RUN SCRIPT IF ANY WERE MISSED`);
} else {
await sleep({ seconds: 2 });
return nextBatch();
}
};
nextBatch();
})();
X shows a "Follows you" badge on users who follow you back. The script looks for [data-testid="userFollowIndicator"] and skips those users.
๐ง 3. Smart Unfollow with Whitelist
๐ What This Does
Unfollows non-followers BUT lets you keep specific accounts you want to keep following (like celebrities, brands, or news accounts that never follow back).
๐ฏ Quick Start
- Edit the
WHITELISTarray with usernames you want to keep - Go to
x.com/YOUR_USERNAME/following - Open DevTools and paste the code
// Smart Unfollow - Non-followers with whitelist
// by nichxbt - https://github.com/nirholas/XActions
(() => {
// โฌ๏ธ ADD USERNAMES TO KEEP (without @)
const WHITELIST = [
'elonmusk',
'naval',
'paulg',
// Add more usernames here...
];
const $followButtons = '[data-testid$="-unfollow"]';
const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
const $userCell = '[data-testid="UserCell"]';
let unfollowedCount = 0;
let skippedCount = 0;
let retry = { count: 0, limit: 3 };
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const scrollToBottom = () => window.scrollTo(0, document.body.scrollHeight);
const getUsernameFromCell = (cell) => {
const link = cell.querySelector('a[href^="/"]');
if (link) {
const href = link.getAttribute('href');
return href.replace('/', '').toLowerCase();
}
return null;
};
const isWhitelisted = (username) => {
return WHITELIST.map(u => u.toLowerCase()).includes(username?.toLowerCase());
};
const followsBack = (cell) => {
return cell.querySelector('[data-testid="userFollowIndicator"]') !== null;
};
const unfollowUser = async (unfollowBtn) => {
unfollowBtn.click();
await sleep(800);
const confirmBtn = document.querySelector($confirmButton);
if (confirmBtn) {
confirmBtn.click();
await sleep(500);
}
};
const processVisible = async () => {
const cells = document.querySelectorAll($userCell);
let processed = 0;
for (const cell of cells) {
const username = getUsernameFromCell(cell);
const unfollowBtn = cell.querySelector($followButtons);
if (!unfollowBtn || !username) continue;
// Skip if follows back
if (followsBack(cell)) {
continue;
}
// Skip if whitelisted
if (isWhitelisted(username)) {
console.log(`โญ๏ธ Skipping @${username} (whitelisted)`);
skippedCount++;
continue;
}
console.log(`๐ Unfollowing @${username}...`);
await unfollowUser(unfollowBtn);
unfollowedCount++;
processed++;
await sleep(1500);
}
return processed > 0;
};
const run = async () => {
console.log('๐ง Smart Unfollow Started');
console.log(`๐ Whitelist: ${WHITELIST.length} accounts protected`);
while (retry.count < retry.limit) {
scrollToBottom();
await sleep(2000);
const didProcess = await processVisible();
if (!didProcess) {
retry.count++;
console.log(`โณ No users found, retry ${retry.count}/${retry.limit}...`);
} else {
retry.count = 0;
}
}
console.log('');
console.log('โ
DONE!');
console.log(`๐ Unfollowed: ${unfollowedCount}`);
console.log(`โญ๏ธ Skipped (whitelisted): ${skippedCount}`);
};
run();
})();
Keep a list of your favorite accounts that never follow back (news, brands, etc.) and add them to your whitelist!
๐ 4. Detect Who Unfollowed You
๐ What This Does
Scans your followers and saves a snapshot. Run it again later to see who unfollowed you! Also shows new followers. Data is saved locally in your browser.
๐ฏ Quick Start
- Go to
x.com/YOUR_USERNAME/followers - Open DevTools and paste the code
- Wait for scan to complete (saves snapshot)
- Run again later to see changes!
// Detect who unfollowed you on X
// by nichxbt - https://github.com/nirholas/XActions
(() => {
const STORAGE_KEY = 'xactions_my_followers';
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
// Check we're on the right page
const isFollowersPage = window.location.pathname.includes('/followers');
if (!isFollowersPage) {
console.error('โ Please navigate to your FOLLOWERS page first!');
console.log('๐ Go to: https://x.com/YOUR_USERNAME/followers');
return;
}
const getCurrentUsername = () => {
const match = window.location.pathname.match(/^\/([^/]+)\/followers/);
return match ? match[1] : 'unknown';
};
const scrapeFollowers = async () => {
const followers = new Set();
let previousSize = 0;
let retries = 0;
const maxRetries = 5;
console.log('๐ Scanning your followers...');
while (retries < maxRetries) {
// Scroll to load more
window.scrollTo(0, document.body.scrollHeight);
await sleep(1500);
// Find all user cells and extract usernames
const userCells = document.querySelectorAll('[data-testid="UserCell"]');
userCells.forEach(cell => {
const usernameEl = cell.querySelector('a[href^="/"]');
if (usernameEl) {
const href = usernameEl.getAttribute('href');
const username = href.replace('/', '').toLowerCase();
if (username && !username.includes('/')) {
followers.add(username);
}
}
});
console.log(` Found ${followers.size} followers so far...`);
if (followers.size === previousSize) {
retries++;
} else {
retries = 0;
previousSize = followers.size;
}
}
return Array.from(followers);
};
const loadPreviousFollowers = () => {
try {
const data = localStorage.getItem(STORAGE_KEY);
if (data) {
return JSON.parse(data);
}
} catch (e) {
console.warn('Could not load previous data:', e);
}
return null;
};
const saveFollowers = (followers, username) => {
const data = {
username,
followers,
timestamp: new Date().toISOString(),
count: followers.length
};
localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
return data;
};
const compareFollowers = (previous, current) => {
const prevSet = new Set(previous.map(f => f.toLowerCase()));
const currSet = new Set(current.map(f => f.toLowerCase()));
const unfollowed = previous.filter(f => !currSet.has(f.toLowerCase()));
const newFollowers = current.filter(f => !prevSet.has(f.toLowerCase()));
return { unfollowed, newFollowers };
};
const formatDate = (isoString) => {
return new Date(isoString).toLocaleString();
};
const run = async () => {
const username = getCurrentUsername();
console.log(`\n๐ฆ XActions Detector โ Monitoring @${username}\n`);
// Scrape current followers
const currentFollowers = await scrapeFollowers();
console.log(`\nโ
Found ${currentFollowers.length} total followers\n`);
// Check for previous data
const previousData = loadPreviousFollowers();
if (previousData && previousData.username === username) {
console.log(`๐ Comparing with snapshot from ${formatDate(previousData.timestamp)}`);
console.log(` Previous count: ${previousData.count}`);
console.log(` Current count: ${currentFollowers.length}`);
console.log('');
const { unfollowed, newFollowers } = compareFollowers(previousData.followers, currentFollowers);
if (unfollowed.length > 0) {
console.log(`\n๐จ ${unfollowed.length} PEOPLE UNFOLLOWED YOU:\n`);
unfollowed.forEach((u, i) => {
console.log(` ${i + 1}. @${u} โ https://x.com/${u}`);
});
} else {
console.log('โจ No one unfollowed you since last check!');
}
if (newFollowers.length > 0) {
console.log(`\n๐ ${newFollowers.length} NEW FOLLOWERS:\n`);
newFollowers.forEach((u, i) => {
console.log(` ${i + 1}. @${u} โ https://x.com/${u}`);
});
}
// Offer download of unfollowers
if (unfollowed.length > 0) {
const blob = new Blob([unfollowed.join('\n')], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `unfollowers-${new Date().toISOString().split('T')[0]}.txt`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
console.log('\n๐ฅ Downloaded list of unfollowers!');
}
} else {
console.log('๐ธ First scan! Saving snapshot of your followers...');
console.log(' Run this script again later to detect changes.');
}
// Save current state
const saved = saveFollowers(currentFollowers, username);
console.log(`\n๐พ Snapshot saved at ${formatDate(saved.timestamp)}`);
console.log(' Run this script again anytime to check for changes!\n');
};
run();
})();
Your follower data is saved in your browser's localStorage under the key xactions_my_followers. It stays on your computer and is never sent anywhere.
๐ฆ Node.js / CLI Method
You can also use XActions from the command line:
# Install XActions globally
npm install -g xactions
# Unfollow everyone (requires auth cookie)
npx xactions unfollow --all
# Unfollow non-followers only
npx xactions unfollow --non-followers
# Get list of non-followers
npx xactions analyze non-followers @yourusername
โ ๏ธ Important Notes
- Rate Limits: X may temporarily limit your account if you unfollow too fast. The scripts include delays to minimize this risk.
- No Undo: Unfollows cannot be undone automatically. You'd need to re-follow accounts manually.
- Page Navigation: Don't navigate away while scripts are running - they stop when you leave the page.
- Large Lists: For accounts following 10,000+ people, run the script multiple times with refreshes.
- Best Practice: Start during off-peak hours and don't run multiple automation scripts simultaneously.