Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Last active April 16, 2025 19:28

Revisions

  1. JamieMason revised this gist Dec 4, 2024. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions unfollow.js.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,7 @@
    # Unfollow everyone on twitter.com

    By [@foldleft.bsky.social](https://bsky.app/profile/foldleft.bsky.social), see also [Unfollow everyone on bsky.app](https://gist.github.com/JamieMason/c0becfbb42d3b358b38cc4b9186584ff).

    1. Go to `https://twitter.com/YOUR_USER_NAME/following`
    2. Open the Developer Console. (<kbd>COMMAND</kbd>+<kbd>ALT</kbd>+<kbd>I</kbd> on Mac)
    3. Paste this into the Developer Console and run it
  2. JamieMason renamed this gist Oct 30, 2023. 1 changed file with 20 additions and 1 deletion.
    21 changes: 20 additions & 1 deletion unfollow.js → unfollow.js.md
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,18 @@
    # Unfollow everyone on twitter.com

    1. Go to `https://twitter.com/YOUR_USER_NAME/following`
    2. Open the Developer Console. (<kbd>COMMAND</kbd>+<kbd>ALT</kbd>+<kbd>I</kbd> on Mac)
    3. Paste this into the Developer Console and run it

    ```js
    // Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)
    // https://gist.github.com/JamieMason/7580315
    //
    // 1. Go to https://twitter.com/YOUR_USER_NAME/following
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    //
    // Last Updated: 09 April 2020
    // Last Updated: 30 October 2023
    (() => {
    const $followButtons = '[data-testid$="-unfollow"]';
    const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
    @@ -63,3 +70,15 @@

    nextBatch();
    })();
    ```

    This script:

    - Is completely free and has been since 2013.
    - Doesn't try and get you to sign in or take your personal data.
    - Automates your web browser to make it click unfollow buttons, scroll down to reveal more, then do it again.
    - No tricks, all of the code is here so you can see exactly what it does.

    If this script was useful and saved you time, maybe kick in for a Coffee to say thanks:

    [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/C0C4PY4P)
  3. JamieMason revised this gist Dec 13, 2021. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -5,9 +5,6 @@
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    //
    // See this tweet by @jacknotlittle for a video showing you how to do it;
    // https://twitter.com/jacknotlittle/status/1387471283525459969
    //
    // Last Updated: 09 April 2020
    (() => {
    const $followButtons = '[data-testid$="-unfollow"]';
  4. JamieMason revised this gist Apr 29, 2021. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,9 @@
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    //
    // See this tweet by @jacknotlittle for a video showing you how to do it;
    // https://twitter.com/jacknotlittle/status/1387471283525459969
    //
    // Last Updated: 09 April 2020
    (() => {
    const $followButtons = '[data-testid$="-unfollow"]';
  5. JamieMason revised this gist Apr 9, 2020. 1 changed file with 42 additions and 22 deletions.
    64 changes: 42 additions & 22 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -4,41 +4,61 @@
    // 1. Go to https://twitter.com/YOUR_USER_NAME/following
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    //
    // Last Updated: 09 April 2020
    (() => {
    const followButtonQuery = '[data-testid$="-unfollow"]';
    const confirmButtonQuery = '[data-testid="confirmationSheetConfirm"]';
    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 => {
    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 () => {
    window.scrollTo(0, document.body.scrollHeight);
    scrollToTheBottom();
    await sleep({ seconds: 1 });

    const followButtons = Array.from(document.querySelectorAll(followButtonQuery));
    const followButtonCount = followButtons.length;
    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 (followButtonCount === 0) {
    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`);
    return;
    } else {
    await sleep({ seconds: 2 });
    return nextBatch();
    }

    console.log(`UNFOLLOWING ${followButtonCount} USERS...`);

    await Promise.all(
    followButtons.map(async followButton => {
    followButton.click();
    await sleep({ seconds: 1 });
    const confirmButton = document.querySelector(confirmButtonQuery);
    confirmButton.click();
    })
    );

    await sleep({ seconds: 2 });
    nextBatch();
    };

    nextBatch();
  6. JamieMason revised this gist Aug 22, 2019. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,5 @@
    // ====================
    // UPDATED 13 AUG 2019
    // ====================
    // Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)
    // https://gist.github.com/JamieMason/7580315
    //
    // 1. Go to https://twitter.com/YOUR_USER_NAME/following
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    @@ -16,6 +14,9 @@
    });

    const nextBatch = async () => {
    window.scrollTo(0, document.body.scrollHeight);
    await sleep({ seconds: 1 });

    const followButtons = Array.from(document.querySelectorAll(followButtonQuery));
    const followButtonCount = followButtons.length;

  7. JamieMason revised this gist Aug 13, 2019. 1 changed file with 26 additions and 19 deletions.
    45 changes: 26 additions & 19 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -7,31 +7,38 @@
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    (() => {
    const sleep = ({ seconds }) => new Promise(proceed => setTimeout(proceed, seconds * 1000));
    const followButtonQuery = '[data-testid$="-unfollow"]';
    const confirmButtonQuery = '[data-testid="confirmationSheetConfirm"]';
    const sleep = ({ seconds }) =>
    new Promise(proceed => {
    console.log(`WAITING FOR ${seconds} SECONDS...`);
    setTimeout(proceed, seconds * 1000);
    });

    const nextBatch = async () => {
    const followButtonQuery = '[data-testid$="-unfollow"]';
    const confirmButtonQuery = '[data-testid="confirmationSheetConfirm"]';
    const followButtons = Array.from(document.querySelectorAll(followButtonQuery));
    const followButtonCount = followButtons.length;

    if (followButtonCount > 0) {
    console.log(`UNFOLLOWING ${followButtonCount} USERS...`);
    await Promise.all(
    followButtons.map(async followButton => {
    followButton.click();
    await sleep({ seconds: 1 });
    const confirmBtn = document.querySelector(confirmButtonQuery);
    confirmBtn.click();
    })
    );

    console.log(`WAITING FOR 2 SECONDS...`);
    await sleep({ seconds: 2 });
    nextBatch();
    } else {
    console.log(`I THINK WE'RE DONE, RE-RUN THE SCRIPT IF ANY WERE MISSED`);
    if (followButtonCount === 0) {
    console.log(`NO ACCOUNTS FOUND, SO I THINK WE'RE DONE`);
    console.log(`RELOAD PAGE AND RE-RUN SCRIPT IF ANY WERE MISSED`);
    return;
    }

    console.log(`UNFOLLOWING ${followButtonCount} USERS...`);

    await Promise.all(
    followButtons.map(async followButton => {
    followButton.click();
    await sleep({ seconds: 1 });
    const confirmButton = document.querySelector(confirmButtonQuery);
    confirmButton.click();
    })
    );

    await sleep({ seconds: 2 });
    nextBatch();
    };

    nextBatch();
    })();
  8. JamieMason revised this gist Aug 13, 2019. 1 changed file with 23 additions and 10 deletions.
    33 changes: 23 additions & 10 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,34 @@
    // ====================
    // UPDATED 23 JULY 2019
    // UPDATED 13 AUG 2019
    // ====================
    // Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)
    //
    // 1. Go to https://twitter.com/YOUR_USER_NAME/following
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    (() => {
    const nextBatch = () => {
    const waitFor = 2;
    const nextBatch = Array.from(document.querySelectorAll('[data-testid$="-unfollow"]'));
    const batchSize = nextBatch.length;
    if (batchSize > 0) {
    console.log(`UNFOLLOWING ${batchSize} USERS...`);
    nextBatch.forEach((button) => button.click());
    console.log(`WAITING FOR ${waitFor} SECONDS...`);
    setTimeout(nextBatch, waitFor * 1000);
    const sleep = ({ seconds }) => new Promise(proceed => setTimeout(proceed, seconds * 1000));

    const nextBatch = async () => {
    const followButtonQuery = '[data-testid$="-unfollow"]';
    const confirmButtonQuery = '[data-testid="confirmationSheetConfirm"]';
    const followButtons = Array.from(document.querySelectorAll(followButtonQuery));
    const followButtonCount = followButtons.length;

    if (followButtonCount > 0) {
    console.log(`UNFOLLOWING ${followButtonCount} USERS...`);
    await Promise.all(
    followButtons.map(async followButton => {
    followButton.click();
    await sleep({ seconds: 1 });
    const confirmBtn = document.querySelector(confirmButtonQuery);
    confirmBtn.click();
    })
    );

    console.log(`WAITING FOR 2 SECONDS...`);
    await sleep({ seconds: 2 });
    nextBatch();
    } else {
    console.log(`I THINK WE'RE DONE, RE-RUN THE SCRIPT IF ANY WERE MISSED`);
    }
  9. JamieMason revised this gist Jul 23, 2019. 1 changed file with 23 additions and 10 deletions.
    33 changes: 23 additions & 10 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,24 @@
    // ====================
    // UPDATED 23 JULY 2019
    // ====================
    // Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)

    // 1. Go to https://twitter.com/following.
    // 2. Keep scrolling to the bottom repeatedly until all your followers are loaded.
    // 3. Run this in your console.
    [].slice.call(document.querySelectorAll('.unfollow-text')).forEach(function(button) {
    button.click();
    });

    // If your browser is freezing because you follow *loads* of people, then try the version
    // in this comment: https://gist.github.com/JamieMason/7580315#gistcomment-2316858
    //
    // 1. Go to https://twitter.com/YOUR_USER_NAME/following
    // 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
    // 3. Paste this into the Developer Console and run it
    (() => {
    const nextBatch = () => {
    const waitFor = 2;
    const nextBatch = Array.from(document.querySelectorAll('[data-testid$="-unfollow"]'));
    const batchSize = nextBatch.length;
    if (batchSize > 0) {
    console.log(`UNFOLLOWING ${batchSize} USERS...`);
    nextBatch.forEach((button) => button.click());
    console.log(`WAITING FOR ${waitFor} SECONDS...`);
    setTimeout(nextBatch, waitFor * 1000);
    } else {
    console.log(`I THINK WE'RE DONE, RE-RUN THE SCRIPT IF ANY WERE MISSED`);
    }
    };
    nextBatch();
    })();
  10. JamieMason revised this gist Jan 10, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    // Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)

    // 1. Go to https://twitter.com/following.
    // 2. Keep scrolling to the bottom repeatedly until all your followers are loaded.
    // 3. Run this in your console.
  11. JamieMason revised this gist Jan 10, 2018. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -4,3 +4,6 @@
    [].slice.call(document.querySelectorAll('.unfollow-text')).forEach(function(button) {
    button.click();
    });

    // If your browser is freezing because you follow *loads* of people, then try the version
    // in this comment: https://gist.github.com/JamieMason/7580315#gistcomment-2316858
  12. JamieMason revised this gist Jul 16, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion unfollow.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // 1. Go to https://twitter.com/following.
    // 2. Keep scrolling to the bottom repeatedly until all your followers are loaded.
    // 3. Run this in your console.
    [].slice.call(document.querySelectorAll('stream-container .unfollow-text')).forEach(function(button) {
    [].slice.call(document.querySelectorAll('.unfollow-text')).forEach(function(button) {
    button.click();
    });
  13. JamieMason created this gist Nov 21, 2013.
    6 changes: 6 additions & 0 deletions unfollow.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    // 1. Go to https://twitter.com/following.
    // 2. Keep scrolling to the bottom repeatedly until all your followers are loaded.
    // 3. Run this in your console.
    [].slice.call(document.querySelectorAll('stream-container .unfollow-text')).forEach(function(button) {
    button.click();
    });