☢️ Unfollow Everyone
The nuclear option - unfollow ALL accounts you're following on X (Twitter).
⚠️ MAJOR WARNING - READ FIRST!
🚨 THIS ACTION IS IRREVERSIBLE!
This script will unfollow EVERYONE you follow. There is no undo button.
X/Twitter does not provide a way to restore your following list.Before proceeding:
- ✅ Export your following list as a backup (scripts do this automatically)
- ✅ Download the backup file and store it safely
- ✅ Consider if you really want to do this
- ✅ Have coffee and think about it again
You cannot recover your following list after running this script!
📋 What It Does
This is the nuclear option for your X/Twitter account:
- Unfollows EVERYONE - Every single account you follow, gone
- No exceptions - Friends, celebrities, brands, everyone
- Complete reset - Takes your following count to zero
- Permanent action - Cannot be undone automatically
Use cases:
- Fresh start on your X account
- Privacy reset (removing all social connections)
- Account cleanup before rebranding
- Escaping an account takeover situation
- Starting over with a curated following list
- Detox from social media algorithm manipulation
This is NOT for:
- ❌ Unfollowing just non-followers (use unfollow-non-followers.md instead)
- ❌ Unfollowing a few specific accounts (do that manually)
- ❌ Testing or "just to see what happens"
🌐 Example 1: Browser Console (Quick)
Best for: Accounts following up to ~500 users
Steps:
- Go to
x.com/YOUR_USERNAME/following - Open browser console (F12 → Console tab)
- Paste the script below and press Enter
- Confirm when prompted
// ============================================
// XActions - Unfollow Everyone (Browser Console)
// Author: nich (@nichxbt)
// Go to: x.com/YOUR_USERNAME/following
// Open console (F12), paste this
// ============================================
(async () => {
// Configuration
const UNFOLLOW_DELAY_MIN = 3000; // Minimum delay between unfollows (ms)
const UNFOLLOW_DELAY_MAX = 5000; // Maximum delay between unfollows (ms)
const SCROLL_DELAY = 2000; // Time between scrolls (ms)
const BATCH_PAUSE = 30000; // Pause every 10 unfollows (ms)
const MAX_SCROLL_RETRIES = 15; // Stop scrolling if no new users found
console.log('');
console.log('☢️ XActions - UNFOLLOW EVERYONE');
console.log('====================================');
console.log('⚠️ WARNING: This will unfollow ALL accounts!');
console.log('⚠️ This action CANNOT be undone!');
console.log('');
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const randomDelay = (min, max) => sleep(min + Math.random() * (max - min));
// Verify we're on the following page
const pathMatch = window.location.pathname.match(/^\/([^/]+)\/following/);
if (!pathMatch) {
console.error('❌ Please navigate to your FOLLOWING page first!');
console.log('👉 Go to: x.com/YOUR_USERNAME/following');
return;
}
const currentUsername = pathMatch[1];
console.log(`📍 Account: @${currentUsername}`);
console.log('');
// ============================================
// Step 1: Scan all users you're following
// ============================================
console.log('📜 Step 1: Scanning your following list...');
console.log(' (This may take a while for large lists)');
const users = new Map();
let scrollRetries = 0;
while (scrollRetries < MAX_SCROLL_RETRIES) {
const cells = document.querySelectorAll('[data-testid="UserCell"]');
const prevSize = users.size;
cells.forEach(cell => {
try {
const link = cell.querySelector('a[href^="/"]');
const href = link?.getAttribute('href') || '';
const username = href.split('/')[1];
if (!username || username.includes('?') || username.includes('/')) return;
const nameEl = cell.querySelector('[dir="ltr"] > span');
const name = nameEl?.textContent?.trim() || username;
const bioEl = cell.querySelector('[data-testid="UserDescription"]');
const bio = bioEl?.textContent?.trim() || '';
if (!users.has(username)) {
users.set(username, {
username,
name,
bio,
cell
});
}
} catch (e) {
// Skip malformed cells
}
});
// Progress update
console.log(` 📊 Found: ${users.size} users`);
if (users.size === prevSize) {
scrollRetries++;
} else {
scrollRetries = 0;
}
// Scroll to load more
window.scrollTo(0, document.body.scrollHeight);
await sleep(SCROLL_DELAY);
}
const allUsers = Array.from(users.values());
console.log('');
console.log(` ✅ Total accounts found: ${allUsers.length}`);
if (allUsers.length === 0) {
console.log('');
console.log('🎉 You\'re not following anyone! Nothing to do.');
return;
}
// ============================================
// Step 2: Export backup before unfollowing
// ============================================
console.log('');
console.log('💾 Step 2: Creating backup of your following list...');
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const exportData = allUsers.map(u => ({
username: u.username,
name: u.name,
bio: u.bio,
exportedAt: new Date().toISOString()
}));
// Download JSON backup
const json = JSON.stringify(exportData, null, 2);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `following-backup-${currentUsername}-${timestamp}.json`;
a.click();
URL.revokeObjectURL(url);
console.log(` 📥 Backup downloaded: following-backup-${currentUsername}-${timestamp}.json`);
console.log(' ⚠️ KEEP THIS FILE SAFE! It\'s your only way to know who you followed.');
// Also copy to clipboard
try {
await navigator.clipboard.writeText(json);
console.log(' 📋 Also copied to clipboard!');
} catch (e) {
// Clipboard might not be available
}
// ============================================
// Step 3: Show summary and get confirmation
// ============================================
console.log('');
console.log('====================================');
console.log('⚠️ FINAL WARNING');
console.log('====================================');
console.log(`You are about to unfollow ${allUsers.length} accounts.`);
console.log('');
console.log('Preview of accounts to unfollow:');
allUsers.slice(0, 10).forEach((u, i) => {
console.log(` ${i + 1}. @${u.username} (${u.name})`);
});
if (allUsers.length > 10) {
console.log(` ... and ${allUsers.length - 10} more`);
}
console.log('');
// Confirmation prompt
const confirmed = window.confirm(
`☢️ NUCLEAR OPTION: Unfollow ALL ${allUsers.length} accounts?\n\n` +
`This action CANNOT be undone!\n\n` +
`Your backup has been downloaded.\n` +
`Click OK to proceed, Cancel to abort.`
);
if (!confirmed) {
console.log('');
console.log('👋 Cancelled! No accounts were unfollowed.');
console.log(' Your backup file has been saved.');
return { unfollowed: [], total: allUsers.length, cancelled: true };
}
console.log('');
console.log('☢️ CONFIRMED - Starting unfollow process...');
console.log(' Press Ctrl+C or close this tab to stop!');
console.log('');
// ============================================
// Step 4: Unfollow everyone
// ============================================
console.log('🚫 Step 4: Unfollowing all accounts...');
console.log('');
const unfollowed = [];
const failed = [];
let consecutiveFailures = 0;
const MAX_CONSECUTIVE_FAILURES = 5;
// Scroll back to top
window.scrollTo(0, 0);
await sleep(1000);
for (let i = 0; i < allUsers.length; i++) {
const user = allUsers[i];
try {
// Find current unfollow buttons on screen
const unfollowButtons = document.querySelectorAll('[data-testid$="-unfollow"]');
if (unfollowButtons.length === 0) {
// Need to scroll to find more buttons
window.scrollTo(0, 0);
await sleep(1500);
const retryButtons = document.querySelectorAll('[data-testid$="-unfollow"]');
if (retryButtons.length === 0) {
console.log(' ⏭️ No more unfollow buttons found, checking if done...');
break;
}
}
// Click the first available unfollow button
const unfollowBtn = document.querySelector('[data-testid$="-unfollow"]');
if (!unfollowBtn) {
consecutiveFailures++;
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
console.log(' ⚠️ Multiple failures in a row, might be rate limited or done');
break;
}
continue;
}
// Get username from the cell
const cell = unfollowBtn.closest('[data-testid="UserCell"]');
let username = 'unknown';
if (cell) {
const link = cell.querySelector('a[href^="/"]');
username = link?.getAttribute('href')?.split('/')[1] || 'unknown';
}
// Click unfollow
unfollowBtn.click();
await sleep(500);
// Click confirmation dialog
const confirmBtn = document.querySelector('[data-testid="confirmationSheetConfirm"]');
if (confirmBtn) {
confirmBtn.click();
unfollowed.push(username);
consecutiveFailures = 0;
const progress = ((i + 1) / allUsers.length * 100).toFixed(1);
console.log(` ✅ ${unfollowed.length} unfollowed | @${username} | ${progress}% complete`);
} else {
failed.push({ username, reason: 'No confirm dialog' });
console.log(` ⚠️ @${username} - Confirm dialog not found`);
consecutiveFailures++;
}
// Wait between unfollows (3-5 seconds with randomization)
await randomDelay(UNFOLLOW_DELAY_MIN, UNFOLLOW_DELAY_MAX);
// Pause every 10 unfollows for safety
if (unfollowed.length % 10 === 0 && unfollowed.length > 0) {
console.log(` ⏸️ Safety pause (${BATCH_PAUSE / 1000}s) - Completed ${unfollowed.length} unfollows...`);
await sleep(BATCH_PAUSE);
console.log(' ▶️ Resuming...');
}
// Check for rate limit warning
const rateLimitWarning = document.querySelector('[data-testid="toast"]');
if (rateLimitWarning?.textContent?.includes('limit')) {
console.log('');
console.log('⛔ RATE LIMIT DETECTED! Stopping to protect your account.');
console.log(' Wait 15-30 minutes before running again.');
break;
}
} catch (error) {
failed.push({ username: user.username, reason: error.message });
console.log(` ❌ Error with @${user.username}: ${error.message}`);
consecutiveFailures++;
}
// Safety check
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
console.log('');
console.log('⚠️ Too many consecutive failures. Stopping.');
break;
}
}
// ============================================
// Step 5: Final summary
// ============================================
console.log('');
console.log('====================================');
console.log('☢️ UNFOLLOW EVERYONE - COMPLETE');
console.log('====================================');
console.log(`📊 Total accounts scanned: ${allUsers.length}`);
console.log(`✅ Successfully unfollowed: ${unfollowed.length}`);
console.log(`❌ Failed: ${failed.length}`);
console.log('');
if (unfollowed.length === allUsers.length) {
console.log('🎉 All accounts have been unfollowed!');
console.log(' Your following count should now be 0.');
} else {
console.log(`💡 ${allUsers.length - unfollowed.length} accounts may remain.`);
console.log(' Refresh the page and run the script again if needed.');
}
console.log('');
console.log('📁 Your backup file: following-backup-' + currentUsername + '-*.json');
console.log(' Use this to manually re-follow accounts if needed.');
// Download results log
const resultsData = {
date: new Date().toISOString(),
account: currentUsername,
totalScanned: allUsers.length,
unfollowed: unfollowed,
failed: failed,
unfollowedCount: unfollowed.length,
failedCount: failed.length
};
const resultsBlob = new Blob([JSON.stringify(resultsData, null, 2)], { type: 'application/json' });
const resultsUrl = URL.createObjectURL(resultsBlob);
const resultsLink = document.createElement('a');
resultsLink.href = resultsUrl;
resultsLink.download = `unfollow-everyone-results-${timestamp}.json`;
resultsLink.click();
URL.revokeObjectURL(resultsUrl);
console.log(`📥 Results saved: unfollow-everyone-results-${timestamp}.json`);
return {
unfollowed,
failed,
total: allUsers.length
};
})();
What happens:
- Script scans your entire following list
- Automatically downloads a backup of everyone you follow
- Shows a confirmation dialog with warning
- Unfollows each account one by one with 3-5 second delays
- Pauses for 30 seconds every 10 unfollows
- Downloads a results log when complete
Safety features:
- ✅ Automatic backup download before any changes
- ✅ Confirmation dialog with clear warning
- ✅ 3-5 second random delay between unfollows
- ✅ 30 second pause every 10 unfollows
- ✅ Automatic stop on rate limit detection
- ✅ Progress tracking in console
🤖 Example 2: Node.js with Puppeteer (Production-Ready)
Best for: Large accounts (500+ following), scheduled runs, complete automation
// ============================================
// XActions - Unfollow Everyone (Node.js/Puppeteer)
// Author: nich (@nichxbt)
// Save as: unfollow-everyone.js
// Run: node unfollow-everyone.js
// ============================================
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import fs from 'fs/promises';
import readline from 'readline';
import path from 'path';
puppeteer.use(StealthPlugin());
// ============================================
// Configuration
// ============================================
const CONFIG = {
// Your X username (without @)
username: 'YOUR_USERNAME',
// Your auth_token cookie from X
// Get this from: Browser DevTools → Application → Cookies → x.com → auth_token
authToken: 'YOUR_AUTH_TOKEN_HERE',
// Maximum users to unfollow per session (for safety)
maxUnfollowsPerSession: 100,
// Delay between unfollows (ms) - random between min and max
unfollowDelayMin: 3000,
unfollowDelayMax: 5000,
// Pause every N unfollows (ms)
batchSize: 10,
batchPauseMin: 25000,
batchPauseMax: 35000,
// Extended pause every 50 unfollows
extendedBatchSize: 50,
extendedPauseMin: 120000, // 2 minutes
extendedPauseMax: 180000, // 3 minutes
// Run in headless mode (set to false to see browser)
headless: true,
// Skip confirmation prompt (⚠️ DANGEROUS!)
skipConfirmation: false,
// Output directory for backups and logs
outputDir: './unfollow-everyone-output',
};
// ============================================
// Helper Functions
// ============================================
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const randomDelay = (min, max) => sleep(min + Math.random() * (max - min));
function log(message, type = 'info') {
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
const prefix = {
info: ' ',
success: ' ✅',
error: ' ❌',
warning: ' ⚠️',
progress: ' 📊',
}[type] || ' ';
console.log(`[${timestamp}]${prefix} ${message}`);
}
async function askConfirmation(question) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise(resolve => {
rl.question(question, answer => {
rl.close();
resolve(answer.toLowerCase().trim());
});
});
}
async function ensureDir(dir) {
try {
await fs.mkdir(dir, { recursive: true });
} catch (e) {
// Directory exists
}
}
// ============================================
// Scrape Following List
// ============================================
async function scrapeFollowingList(page, username, maxUsers = 5000) {
log(`Navigating to @${username}/following...`);
await page.goto(`https://x.com/${username}/following`, {
waitUntil: 'networkidle2',
timeout: 30000
});
try {
await page.waitForSelector('[data-testid="UserCell"]', { timeout: 15000 });
} catch {
log('No users found or page didn\'t load', 'warning');
return [];
}
await sleep(2000);
const users = new Map();
let retries = 0;
const maxRetries = 20;
log('Scanning following list (this may take a while)...');
while (users.size < maxUsers && retries < maxRetries) {
const extracted = await page.evaluate(() => {
const cells = document.querySelectorAll('[data-testid="UserCell"]');
return Array.from(cells).map(cell => {
try {
const link = cell.querySelector('a[href^="/"]');
const href = link?.getAttribute('href') || '';
const username = href.split('/')[1];
if (!username || username.includes('?') || username.includes('/')) return null;
const nameEl = cell.querySelector('[dir="ltr"] > span');
const bioEl = cell.querySelector('[data-testid="UserDescription"]');
return {
username,
name: nameEl?.textContent?.trim() || null,
bio: bioEl?.textContent?.trim() || null,
};
} catch {
return null;
}
}).filter(Boolean);
});
const prevSize = users.size;
extracted.forEach(user => {
if (!users.has(user.username)) {
users.set(user.username, user);
}
});
if (users.size === prevSize) {
retries++;
} else {
retries = 0;
}
process.stdout.write(`\r 📊 Scanned: ${users.size} users...`);
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await randomDelay(1500, 2500);
}
console.log(''); // New line after progress
return Array.from(users.values());
}
// ============================================
// Export Following List as Backup
// ============================================
async function exportBackup(users, username, outputDir) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const backupData = {
exportedAt: new Date().toISOString(),
account: username,
totalCount: users.length,
users: users.map(u => ({
username: u.username,
name: u.name,
bio: u.bio,
}))
};
// Save JSON
const jsonPath = path.join(outputDir, `following-backup-${username}-${timestamp}.json`);
await fs.writeFile(jsonPath, JSON.stringify(backupData, null, 2));
log(`Backup saved: ${jsonPath}`, 'success');
// Save CSV
const csvPath = path.join(outputDir, `following-backup-${username}-${timestamp}.csv`);
const csvHeader = 'username,name,bio';
const csvRows = users.map(u =>
`"${u.username}","${(u.name || '').replace(/"/g, '""')}","${(u.bio || '').replace(/"/g, '""').replace(/\n/g, ' ')}"`
);
await fs.writeFile(csvPath, [csvHeader, ...csvRows].join('\n'));
log(`CSV backup saved: ${csvPath}`, 'success');
// Save simple text list
const txtPath = path.join(outputDir, `following-backup-${username}-${timestamp}.txt`);
const txtContent = users.map(u => `@${u.username}`).join('\n');
await fs.writeFile(txtPath, txtContent);
log(`Text list saved: ${txtPath}`, 'success');
return { jsonPath, csvPath, txtPath, timestamp };
}
// ============================================
// Unfollow a Single User
// ============================================
async function unfollowUser(page, username) {
try {
// Navigate to user's profile
await page.goto(`https://x.com/${username}`, {
waitUntil: 'networkidle2',
timeout: 20000
});
await sleep(1000 + Math.random() * 500);
// Find the "Following" button (which triggers unfollow)
const followingBtn = await page.$('[data-testid$="-unfollow"]');
if (!followingBtn) {
// Check if we're already not following
const followBtn = await page.$('[data-testid$="-follow"]');
if (followBtn) {
return { success: true, alreadyUnfollowed: true };
}
return { success: false, error: 'Follow button not found' };
}
// Click the following button
await followingBtn.click();
await sleep(600);
// Click confirm in the dialog
const confirmBtn = await page.$('[data-testid="confirmationSheetConfirm"]');
if (confirmBtn) {
await confirmBtn.click();
await sleep(500);
return { success: true };
} else {
return { success: false, error: 'Confirm dialog not found' };
}
} catch (error) {
return { success: false, error: error.message };
}
}
// ============================================
// Main Function
// ============================================
async function unfollowEveryone() {
console.log('');
console.log('☢️ ═══════════════════════════════════════════');
console.log('☢️ XACTIONS - UNFOLLOW EVERYONE');
console.log('☢️ ═══════════════════════════════════════════');
console.log('');
console.log('⚠️ WARNING: This will unfollow ALL accounts!');
console.log('⚠️ This action CANNOT be undone!');
console.log('');
console.log(`👤 Account: @${CONFIG.username}`);
console.log(`📊 Max unfollows per session: ${CONFIG.maxUnfollowsPerSession}`);
console.log(`⏱️ Delay between unfollows: ${CONFIG.unfollowDelayMin/1000}-${CONFIG.unfollowDelayMax/1000}s`);
console.log('');
// Validate config
if (CONFIG.username === 'YOUR_USERNAME' || CONFIG.authToken === 'YOUR_AUTH_TOKEN_HERE') {
console.error('❌ Error: Please update CONFIG with your username and auth_token');
console.log('');
console.log('To get your auth_token:');
console.log('1. Go to x.com in your browser and log in');
console.log('2. Press F12 → Application tab → Cookies → x.com');
console.log('3. Find "auth_token" and copy its value');
console.log('4. Paste it in the CONFIG section of this script');
process.exit(1);
}
// Create output directory
await ensureDir(CONFIG.outputDir);
// Launch browser
log('Launching browser...');
const browser = await puppeteer.launch({
headless: CONFIG.headless ? 'new' : false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-blink-features=AutomationControlled',
'--disable-web-security',
],
});
const startTime = Date.now();
const results = {
startTime: new Date().toISOString(),
account: CONFIG.username,
unfollowed: [],
failed: [],
skipped: [],
};
try {
const page = await browser.newPage();
// Set viewport and user agent
await page.setViewport({
width: 1280 + Math.floor(Math.random() * 100),
height: 900 + Math.floor(Math.random() * 100),
});
await page.setUserAgent(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
);
// Set auth cookie
log('Setting authentication...');
await page.setCookie({
name: 'auth_token',
value: CONFIG.authToken,
domain: '.x.com',
path: '/',
httpOnly: true,
secure: true,
});
// Test authentication
await page.goto('https://x.com/home', { waitUntil: 'networkidle2' });
await sleep(2500);
const isLoggedIn = await page.evaluate(() => {
return document.querySelector('[data-testid="SideNav_AccountSwitcher_Button"]') !== null;
});
if (!isLoggedIn) {
throw new Error('Authentication failed. Please check your auth_token.');
}
log('Logged in successfully!', 'success');
console.log('');
// ============================================
// Step 1: Scrape following list
// ============================================
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('📜 STEP 1: Exporting your following list (BACKUP)');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
const following = await scrapeFollowingList(page, CONFIG.username);
log(`Found ${following.length} accounts you follow`, 'success');
console.log('');
if (following.length === 0) {
log('You\'re not following anyone! Nothing to do.', 'success');
return;
}
// ============================================
// Step 2: Export backup
// ============================================
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('💾 STEP 2: Creating backup files');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
const backup = await exportBackup(following, CONFIG.username, CONFIG.outputDir);
console.log('');
log('IMPORTANT: Keep these backup files safe!', 'warning');
log('They are your ONLY way to know who you followed.', 'warning');
console.log('');
// ============================================
// Step 3: Show preview and confirm
// ============================================
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('📋 STEP 3: Review and confirm');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('');
console.log('Preview of accounts to unfollow:');
following.slice(0, 15).forEach((u, i) => {
console.log(` ${(i + 1).toString().padStart(2)}. @${u.username.padEnd(20)} ${u.name || ''}`);
});
if (following.length > 15) {
console.log(` ... and ${following.length - 15} more`);
}
console.log('');
const toUnfollow = following.slice(0, CONFIG.maxUnfollowsPerSession);
console.log('┌──────────────────────────────────────────┐');
console.log('│ ☢️ NUCLEAR OPTION WARNING │');
console.log('├──────────────────────────────────────────┤');
console.log(`│ Total following: ${following.length.toString().padEnd(20)} │`);
console.log(`│ Will unfollow: ${toUnfollow.length.toString().padEnd(22)} │`);
console.log('│ │');
console.log('│ THIS CANNOT BE UNDONE! │');
console.log('└──────────────────────────────────────────┘');
console.log('');
if (!CONFIG.skipConfirmation) {
const answer = await askConfirmation(
`☢️ Type "UNFOLLOW ALL" to confirm (or anything else to cancel): `
);
if (answer !== 'unfollow all') {
console.log('');
log('Cancelled! No accounts were unfollowed.', 'success');
log(`Your backup has been saved to: ${CONFIG.outputDir}`);
return;
}
}
console.log('');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('☢️ STEP 4: Unfollowing all accounts');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('');
log('Press Ctrl+C at any time to stop', 'warning');
console.log('');
// ============================================
// Step 4: Unfollow everyone
// ============================================
for (let i = 0; i < toUnfollow.length; i++) {
const user = toUnfollow[i];
const result = await unfollowUser(page, user.username);
if (result.success) {
if (result.alreadyUnfollowed) {
results.skipped.push(user.username);
log(`${(i + 1).toString().padStart(3)}/${toUnfollow.length} - @${user.username} (already unfollowed)`, 'warning');
} else {
results.unfollowed.push(user.username);
const percent = ((i + 1) / toUnfollow.length * 100).toFixed(1);
log(`${(i + 1).toString().padStart(3)}/${toUnfollow.length} - Unfollowed @${user.username} (${percent}%)`, 'success');
}
} else {
results.failed.push({ username: user.username, error: result.error });
log(`${(i + 1).toString().padStart(3)}/${toUnfollow.length} - Failed @${user.username}: ${result.error}`, 'error');
}
// Standard delay between unfollows
await randomDelay(CONFIG.unfollowDelayMin, CONFIG.unfollowDelayMax);
// Batch pause every N unfollows
if ((i + 1) % CONFIG.batchSize === 0 && i < toUnfollow.length - 1) {
const pauseDuration = Math.floor(CONFIG.batchPauseMin + Math.random() * (CONFIG.batchPauseMax - CONFIG.batchPauseMin));
log(`Safety pause (${Math.round(pauseDuration/1000)}s)...`, 'warning');
await sleep(pauseDuration);
}
// Extended pause every 50 unfollows
if ((i + 1) % CONFIG.extendedBatchSize === 0 && i < toUnfollow.length - 1) {
const extendedPause = Math.floor(CONFIG.extendedPauseMin + Math.random() * (CONFIG.extendedPauseMax - CONFIG.extendedPauseMin));
console.log('');
log(`Extended safety pause (${Math.round(extendedPause/1000)}s) - Completed ${i + 1} unfollows`, 'warning');
await sleep(extendedPause);
console.log('');
}
}
// ============================================
// Step 5: Summary
// ============================================
const duration = Math.round((Date.now() - startTime) / 1000);
console.log('');
console.log('☢️ ═══════════════════════════════════════════');
console.log('☢️ UNFOLLOW EVERYONE - COMPLETE');
console.log('☢️ ═══════════════════════════════════════════');
console.log('');
console.log(`📊 Total accounts found: ${following.length}`);
console.log(`✅ Successfully unfollowed: ${results.unfollowed.length}`);
console.log(`⏭️ Already unfollowed: ${results.skipped.length}`);
console.log(`❌ Failed: ${results.failed.length}`);
console.log(`⏱️ Duration: ${Math.floor(duration/60)}m ${duration%60}s`);
console.log('');
if (following.length > CONFIG.maxUnfollowsPerSession) {
console.log(`💡 ${following.length - CONFIG.maxUnfollowsPerSession} accounts remaining.`);
console.log(' Wait 1-2 hours, then run the script again!');
console.log('');
}
// Save results log
results.endTime = new Date().toISOString();
results.duration = duration;
results.totalFound = following.length;
const resultsPath = path.join(CONFIG.outputDir, `unfollow-results-${backup.timestamp}.json`);
await fs.writeFile(resultsPath, JSON.stringify(results, null, 2));
log(`Results saved: ${resultsPath}`, 'success');
console.log('');
console.log('📁 All files saved to:', CONFIG.outputDir);
console.log(' Keep the backup files to manually re-follow accounts if needed.');
} finally {
await browser.close();
}
}
// ============================================
// Run
// ============================================
unfollowEveryone().catch(error => {
console.error('');
console.error('❌ Fatal Error:', error.message);
process.exit(1);
});
Setup & Run:
# Create a new directory for this script
mkdir unfollow-everyone && cd unfollow-everyone
# Initialize npm project
npm init -y
# Add "type": "module" to package.json for ES modules
npm pkg set type=module
# Install dependencies
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
# Create the script file
# Copy the code above into unfollow-everyone.js
# Edit the CONFIG section with your username and auth_token
# Then run:
node unfollow-everyone.js
Getting your auth_token:
- Log into X/Twitter in your browser
- Press F12 → Application tab (Chrome) or Storage tab (Firefox)
- Click Cookies →
x.com - Find
auth_tokenand copy the value - Paste it in the CONFIG section
Output example:
☢️ ═══════════════════════════════════════════
☢️ XACTIONS - UNFOLLOW EVERYONE
☢️ ═══════════════════════════════════════════
⚠️ WARNING: This will unfollow ALL accounts!
⚠️ This action CANNOT be undone!
👤 Account: @nichxbt
📊 Max unfollows per session: 100
⏱️ Delay between unfollows: 3-5s
[10:23:45] Launching browser...
[10:23:48] Setting authentication...
[10:23:51] ✅ Logged in successfully!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📜 STEP 1: Exporting your following list (BACKUP)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Scanned: 847 users...
[10:24:32] ✅ Found 847 accounts you follow
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💾 STEP 2: Creating backup files
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[10:24:33] ✅ Backup saved: ./unfollow-everyone-output/following-backup-nichxbt-2026-01-01T10-24-33-123Z.json
[10:24:33] ✅ CSV backup saved: ./unfollow-everyone-output/following-backup-nichxbt-2026-01-01T10-24-33-123Z.csv
[10:24:33] ✅ Text list saved: ./unfollow-everyone-output/following-backup-nichxbt-2026-01-01T10-24-33-123Z.txt
[10:24:33] ⚠️ IMPORTANT: Keep these backup files safe!
[10:24:33] ⚠️ They are your ONLY way to know who you followed.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 STEP 3: Review and confirm
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Preview of accounts to unfollow:
1. @elonmusk Elon Musk
2. @OpenAI OpenAI
3. @github GitHub
... and 832 more
┌──────────────────────────────────────────┐
│ ☢️ NUCLEAR OPTION WARNING │
├──────────────────────────────────────────┤
│ Total following: 847 │
│ Will unfollow: 100 │
│ │
│ THIS CANNOT BE UNDONE! │
└──────────────────────────────────────────┘
☢️ Type "UNFOLLOW ALL" to confirm (or anything else to cancel): UNFOLLOW ALL
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
☢️ STEP 4: Unfollowing all accounts
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[10:24:45] ⚠️ Press Ctrl+C at any time to stop
[10:24:50] ✅ 1/100 - Unfollowed @elonmusk (1.0%)
[10:24:55] ✅ 2/100 - Unfollowed @OpenAI (2.0%)
[10:25:00] ✅ 3/100 - Unfollowed @github (3.0%)
...
[10:26:20] ⚠️ Safety pause (30s)...
...
☢️ ═══════════════════════════════════════════
☢️ UNFOLLOW EVERYONE - COMPLETE
☢️ ═══════════════════════════════════════════
📊 Total accounts found: 847
✅ Successfully unfollowed: 100
⏭️ Already unfollowed: 0
❌ Failed: 0
⏱️ Duration: 12m 34s
💡 747 accounts remaining.
Wait 1-2 hours, then run the script again!
[10:37:19] ✅ Results saved: ./unfollow-everyone-output/unfollow-results-2026-01-01T10-24-33-123Z.json
📁 All files saved to: ./unfollow-everyone-output
Keep the backup files to manually re-follow accounts if needed.
⚠️ Safety Guidelines & Rate Limits
Rate Limit Guidelines
| Action | Recommended Limit | Reason |
|---|---|---|
| Unfollows per session | 50-100 | Avoid triggering rate limits |
| Delay between unfollows | 3-5 seconds | Mimics human behavior |
| Batch pause (every 10) | 25-35 seconds | Gives API breathing room |
| Extended pause (every 50) | 2-3 minutes | Major safety break |
| Between sessions | 1-2 hours | Account protection |
| Maximum per day | 200-300 | Stay well under radar |
Warning Signs - STOP IMMEDIATELY If You See:
- ⛔ "You're doing that too fast" message
- ⛔ "Rate limit exceeded" error
- ⛔ Unfollow buttons stop responding
- ⛔ Account gets temporarily restricted
- ⛔ Asked to verify phone number
- ⛔ Multiple consecutive failures
Recovery If Rate Limited
- Stop immediately - Close the script/browser
- Wait at least 2 hours - Let the rate limit reset
- Reduce batch size - Set
maxUnfollowsPerSessionto 25-50 - Increase delays - Double the delay times
- Try again tomorrow - If issues persist, wait 24 hours
🌐 Website Alternative
Don't want to run scripts? Use xactions.app:
- Login - Connect your X account securely
- Backup - Export your entire following list first
- Select - Choose "Unfollow Everyone" option
- Confirm - Multiple confirmation steps for safety
- Execute - Automated unfollowing with built-in rate limits
Benefits:
- ✅ No coding or setup required
- ✅ Automatic backup before any changes
- ✅ Visual progress tracking
- ✅ Built-in rate limit protection
- ✅ Pause and resume capability
- ✅ Email notification when complete
📝 Frequently Asked Questions
Can I undo this?
No. Once you unfollow everyone, there's no automatic way to restore your following list. The only way is to:
- Use your backup file
- Manually follow each account again one by one
How long does this take?
Depends on how many accounts you follow:
- 100 accounts: ~10-15 minutes
- 500 accounts: ~1-2 hours (with safety pauses)
- 1000+ accounts: Multiple sessions over several hours
Will my followers know?
They won't get notified that you unfollowed them. However:
- They may notice if they check their followers
- You'll disappear from their "Following" notifications
- DM history remains intact
Is this against X/Twitter's rules?
Mass unfollowing is a gray area. To stay safe:
- Use reasonable delays (this script does)
- Don't run multiple sessions back-to-back
- Don't combine with other automation at the same time
What about protected accounts I follow?
The script will attempt to unfollow them normally. If it fails, they'll appear in the "failed" list.
📚 Related Documentation
- Detect Unfollowers - Track who unfollowed you
- Unfollow Non-Followers - Only unfollow people who don't follow back
- Following Scraping - Export your following list
Author: nich (@nichxbt)
Part of XActions - X/Twitter Automation Tools
⚡ Ready to try ☢ Unfollow Everyone?
XActions is 100% free and open-source. No API keys, no fees, no signup.
Browse All Scripts