Skip to content

Instantly share code, notes, and snippets.

@eaorak
Created December 4, 2025 22:39
Show Gist options
  • Select an option

  • Save eaorak/160e5794d09bb0638ce49b80b25a84d9 to your computer and use it in GitHub Desktop.

Select an option

Save eaorak/160e5794d09bb0638ce49b80b25a84d9 to your computer and use it in GitHub Desktop.
LinkedIn Unfollow Script
// Go to this page:
//
// https://www.linkedin.com/mynetwork/network-manager/people-follow/following/
//
// Paste this entire file into the DevTools console on your LinkedIn "Following" tab.
// It will iterate through visible "Following" buttons, click each one, confirm the
// unfollow dialog, and keep scrolling until it runs out of people or hits the limit.
// Adjust the CONFIG values to suit your pace/limits before running.
(() => {
const CONFIG = {
maxUnfollows: 300, // Hard stop to avoid endless runs.
betweenClicksMs: 900, // Wait after each confirm click.
confirmWaitMs: 2000, // How long to wait for the confirm dialog.
scrollPauseMs: 1000 // Wait after each scroll for content to load.
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const findFollowingButtons = () =>
Array.from(document.querySelectorAll('button')).filter((btn) => {
const label = btn.textContent?.trim().toLowerCase();
return label === 'following';
});
const waitForConfirmButton = async (timeoutMs) => {
const start = performance.now();
while (performance.now() - start < timeoutMs) {
const btn = Array.from(document.querySelectorAll('button')).find((b) => {
const text = b.textContent?.trim().toLowerCase();
return text === 'unfollow';
});
if (btn) return btn;
await sleep(100);
}
return null;
};
const scrollMore = async () => {
const before = document.body.scrollHeight;
window.scrollBy({ top: window.innerHeight * 0.9, behavior: 'smooth' });
await sleep(CONFIG.scrollPauseMs);
return document.body.scrollHeight > before;
};
const processed = new WeakSet();
let unfollowed = 0;
let failures = 0;
const log = (...args) => console.log('[unfollow]', ...args);
const run = async () => {
log('Starting…');
while (unfollowed < CONFIG.maxUnfollows) {
const buttons = findFollowingButtons().filter((b) => !processed.has(b));
if (buttons.length === 0) {
const grew = await scrollMore();
if (!grew) {
log('No more people found to unfollow.');
break;
}
continue;
}
for (const btn of buttons) {
if (unfollowed >= CONFIG.maxUnfollows) break;
processed.add(btn);
btn.scrollIntoView({ behavior: 'smooth', block: 'center' });
btn.click();
const confirm = await waitForConfirmButton(CONFIG.confirmWaitMs);
if (confirm) {
confirm.click();
unfollowed += 1;
failures = 0;
log(`Unfollowed ${unfollowed}`);
await sleep(CONFIG.betweenClicksMs);
} else {
failures += 1;
log('Confirm dialog not found; skipping this entry.');
await sleep(300);
}
if (failures >= 5) {
log('Too many failures locating the confirm dialog. Stopping.');
return;
}
}
}
log(`Finished. Total unfollowed: ${unfollowed}`);
};
run();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment