Skip to content

Instantly share code, notes, and snippets.

@behnamazimi
Created January 14, 2026 09:45
Show Gist options
  • Select an option

  • Save behnamazimi/2736163efb6cbd2362acae1c503a0f35 to your computer and use it in GitHub Desktop.

Select an option

Save behnamazimi/2736163efb6cbd2362acae1c503a0f35 to your computer and use it in GitHub Desktop.
Find non-followers on X
// Highlights accounts you follow that don't follow you back on X
// Run in browser console while on your Following list
const CELL_SELECTOR = 'div[data-testid="cellInnerDiv"]';
const FOLLOWS_TEXT = 'Follows you';
const nonFollowers = new Set();
let lastScrollHeight = 0;
let stableCount = 0;
function extractUsername(cell) {
const link = cell.querySelector('a[href^="/"]');
return link?.pathname.slice(1) || null;
}
function updateCell(cell) {
const text = cell.innerText;
const username = extractUsername(cell);
if (!username) return;
if (!text.includes(FOLLOWS_TEXT)) {
nonFollowers.add(username);
}
if (nonFollowers.has(username)) {
cell.style.border = '2px solid red';
} else {
cell.style.border = '';
}
}
async function scrollToEnd() {
return new Promise(resolve => {
const interval = setInterval(() => {
const scrollHeight = document.body.scrollHeight;
const viewportHeight = window.innerHeight;
const currentPosition = window.scrollY;
const atBottom = currentPosition + viewportHeight >= scrollHeight - 10;
if (atBottom) {
if (scrollHeight === lastScrollHeight) {
stableCount++;
if (stableCount >= 3) {
clearInterval(interval);
window.scrollTo(0, 0);
console.log(`✓ Found ${nonFollowers.size} non-followers`);
console.log('Export: copy(Array.from(nonFollowers).sort())');
resolve();
}
} else {
stableCount = 0;
lastScrollHeight = scrollHeight;
window.scrollBy(0, viewportHeight);
}
} else {
window.scrollBy(0, viewportHeight);
}
}, 200);
});
}
new MutationObserver(mutations => {
mutations.forEach(m => {
if (m.type === 'childList') {
m.addedNodes.forEach(node => {
if (node.nodeType !== 1) return;
if (node.matches?.(CELL_SELECTOR)) {
updateCell(node);
} else {
node.querySelectorAll?.(CELL_SELECTOR).forEach(updateCell);
}
});
} else {
const cell = m.target.closest?.(CELL_SELECTOR);
if (cell) updateCell(cell);
}
});
}).observe(document.body, {
childList: true,
subtree: true,
characterData: true,
attributes: true
});
scrollToEnd();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment