Clean up your Twitter following list automatically. Unfollow accounts outside your niche while protecting mutual follows.
A high following/follower ratio (e.g. 1000 following / 150 followers) signals "spam account" to visitors. Cleaning up to a healthy ratio (< 2:1) is one of the highest-leverage things you can do for follower growth.
Doing it manually takes hours. This script does it in ~20 minutes.
- Fetches your full Following list via Twitter's internal API
- Fetches your Followers to detect mutual follows
- Categorizes every account by name + bio keywords (AI, builder, tech, VC, design, etc.)
- Protects mutuals and accounts in your chosen niche categories
- Shows you the full plan — nothing is unfollowed until you confirm
- Unfollows the rest with smart rate-limit handling
This is a single-file script. No installs, no dependencies, no build step.
Open twitter-unfollow-cleanup.js and copy all the contents (Ctrl+A then Ctrl+C).
- Go to x.com and make sure you are logged in
- Open DevTools:
- Chrome/Edge: Press
F12orCtrl+Shift+J(Mac:Cmd+Option+J) - Firefox: Press
F12orCtrl+Shift+K(Mac:Cmd+Option+K)
- Chrome/Edge: Press
- Click the Console tab
Chrome blocks pasting in the console by default. You will see a warning like:
Warning: Don't paste code into the DevTools Console that you don't understand...
Type allow pasting and press Enter. This enables pasting for the current session.
- Paste the script (Ctrl+V) and press Enter
- It auto-starts: runs a preflight check, fetches your accounts, categorizes them, and shows a plan
- Review the plan:
tuc.showKeep()— see who you're keepingtuc.showUnfollow()— see who will be unfollowed
- When you're satisfied, type
tuc.execute()and press Enter to start unfollowing
| Command | Description |
|---|---|
tuc.run() |
Fetch accounts, categorize, show plan |
tuc.execute() |
Start unfollowing (only after reviewing the plan) |
tuc.stop() |
Pause mid-run |
tuc.resume() |
Continue from where you paused |
tuc.status() |
Check progress |
tuc.showKeep() |
Table of accounts being kept |
tuc.showUnfollow() |
Table of accounts to be unfollowed |
tuc.exportUnfollowList() |
Download unfollow list as JSON |
tuc.preflight() |
Re-run login/session check |
Edit the config before running, or modify it live via tuc.config:
// Categories to keep (accounts in these categories won't be unfollowed)
tuc.config.KEEP_CATEGORIES = ['ai', 'builder', 'tech', 'vc', 'design'];
// Add/remove categories dynamically
tuc.addKeepCategory('crypto');
tuc.removeKeepCategory('design');
tuc.recategorize(); // re-run with new config
// Timing (milliseconds)
tuc.config.UNFOLLOW_DELAY_MS = 8000; // 8s between unfollows
tuc.config.RATE_LIMIT_COOLDOWN_MS = 720000; // 12 min on rate limit
// Always protect mutual follows
tuc.config.ALWAYS_KEEP_MUTUALS = true;The script categorizes accounts by matching name + bio text against keyword lists. Customize tuc.config.CATEGORY_KEYWORDS to match your niche:
tuc.config.CATEGORY_KEYWORDS.ai.push('robotics', 'autonomous');
tuc.config.CATEGORY_KEYWORDS.builder.push('no-code', 'low-code');Twitter limits unfollows to ~30 per burst. The script handles this automatically:
- 8 second delay between each unfollow (avoids triggering limits too fast)
- 12 minute cooldown when rate-limited (Twitter's reset window)
- 3 retries per account before skipping
- ~20 min per 100 unfollows including rate limit pauses
Total time for 500 unfollows: roughly 1.5-2 hours. Start it and let it run.
- Mutuals are always protected — anyone who follows you back is never unfollowed
- Dry run by default — the script shows you the full plan before unfollowing anything
- Pause anytime —
tuc.stop()pauses,tuc.resume()continues - No tokens or API keys needed — runs using your existing browser session
- Nothing is installed — just a script in your browser console
- Don't close the tab while it's running — progress is lost if you close it
- GraphQL endpoint hashes rotate when X deploys updates — the script auto-detects current hashes from the page, and falls back to stable REST endpoints if GraphQL fails
- New accounts you follow between runs aren't included — re-run
tuc.run()for a fresh scan - Works on desktop browsers only (Chrome, Firefox, Edge)
The package.json, eslint.config.cjs, and checks/ folder are development-only tooling. End users don't need them.
To run the dev checks locally:
npm install
npm test # lint + smoke checkThe smoke check runs a mock end-to-end test (fake data, no real API calls) to verify the script loads and categorizes correctly.
MIT