There are multiple efficient methods to delete all tweets without having to delete your entire X account. Whether you’re looking to remove embarrassing tweets or just want a clean slate, you have complete control over your account’s content.

This post provides practical guidance on why and how to delete tweets, offering various methods to manage old Twitter content effectively. Clearing your history can help prevent potential issues, such as public relations challenges from old, outdated posts.

We’ll walk you through the simplest ways to refresh your X account while keeping it active. Explore these options to make the process straightforward and efficient!

Why Delete Old Tweets?

There are several reasons you might need to delete tweets:

  1. You have a Twitter account with past posts that could be seen as inappropriate or outdated;
  2. You’ve recently taken over a client’s X account and don’t know what previous content may contain.

In either situation, clearing old tweets gives the account a clean slate, helping maintain a professional or brand-consistent appearance.

After reviewing the reasons for deleting tweets, this post will outline essential features to look for in deletion tools. These features will help you choose the right tools to manage your content, enabling an effective and controlled Twitter refresh.

With a range of methods and tools available, you’ll have options to decide on the best approach based on your specific needs.

Deciding How Many Tweets to Delete

X limits third-party applications to accessing the most recent 3,200 tweets on your timeline. This restriction means that while only 3,200 tweets are readily accessible through certain tools, your older tweets still exist and can be retrieved through other methods.

When planning for deletion, consider if you need to remove fewer than 3,200 tweets or clear your entire history. Depending on your goal, various methods and tools are available to help you achieve the desired level of account cleanup.

Additionally, if you need to clean up who you follow, you can also use solutions that allow you to mass unfollow Twitter accounts, helping you streamline your network alongside tweet deletion

Manual Deletion of Tweets

The simplest way to delete tweets is to go through your account and manually delete each tweet individually. This method is suitable for beginners or those who want to retain most of their tweets while removing specific posts selectively.

Reasons to manually delete tweets:

  • Selective Deletion: If you want to keep most of your content and only remove specific tweets, the manual approach allows you to carefully choose which tweets to delete;
  • Client Account Management: Social media managers often use this method when taking over a client’s account to review and delete tweets that may not align with the client’s current image or goals. This approach helps in identifying potentially problematic tweets without losing valuable content;
  • Content Clean-Up: This method is commonly used to remove outdated or inappropriate content while keeping the core of the account intact.

While manual deletion offers control, it can be time-consuming if you have a large number of tweets. For accounts with a significant amount of content, bulk-deletion tools may be more efficient.

Deleting Fewer Than 3,200 Tweets

TweetEraser

TweetEraser is a web-based tool designed for users who want to delete large numbers of tweets quickly and efficiently. While the free version allows for the deletion of up to 3,200 tweets, paid plans enable more extensive cleanups. The standard plan is available for $6.99 per month, while the premium plan costs $9.99 per month.

This tool uses advanced search filters to ensure that only the tweets you want deleted are removed, leaving no unwanted content behind. Its user-friendly interface is simple to use, even for those new to bulk tweet deletion.

How to use TweetEraser in six simple steps:

  1. Visit the TweetEraser Website: Choose your plan—either the free version for basic needs or a paid plan for more features;
  2. Sign In with X: Select “Sign in with Twitter” and authorize the app by entering your Twitter login details. You may be prompted to enter an authentication code;
  3. Authorize the App: Input the code if needed and complete the authorization process;
  4. Access Your Tweets: Upload your X data file to start the deletion process from your tweet archive;
  5. Select “Delete Tweets”: Once you’ve uploaded the archive, select the “Delete Tweets” option;
  6. Confirm Deletion: Confirm your choice, and TweetEraser will begin deleting your tweets. The process may take some time to complete, depending on the volume of tweets.

After completing these steps, TweetEraser will remove the selected tweets, giving your account a fresh start. With this option covered, let’s look at other methods to delete tweets effectively.

Twilert

Twilert is a Twitter monitoring tool designed to help users track specific keywords, hashtags, and handles in real time, offering practical insights for brands, PR professionals, and agencies. While it doesn’t support bulk tweet deletion, Twilert’s old tweets feature lets users filter tweets within an account, making it useful for finding and selectively deleting specific posts, retweets, or likes.

Twilert’s features include geo-targeting, scheduled alerts, and email digests, keeping users informed of relevant conversations. It supports complex Boolean search queries and can capture tweets that standard X search might miss. Additional options for user grouping and white-labeling make Twilert a flexible tool for brand monitoring, PR outreach, and competitive analysis.

Deleting More Than 3,200 Tweets

Circleboom

Circleboom is a versatile Twitter management tool that offers extensive account insights, follower analysis, and tweet deletion services. Circleboom is perfect for users looking to manage their X profiles comprehensively, with options to delete tweets, retweets, and even detect inactive or spam accounts.

Key Features of Circleboom:

  • Account Analytics and Insights: Gain valuable insights into followers, inactive accounts, and potential spam to keep your Twitter network active and relevant;
  • Bulk Deletion of Tweets and Retweets: Clean up your X feed by removing all tweets and retweets in one go, whether on mobile or desktop;
  • Comprehensive Twitter Management: Beyond tweet deletion, Circleboom includes tools for managing account health, detecting fake followers, and monitoring follower activity.

Circleboom is a convenient, all-in-one solution for users who want to maintain a polished X profile with minimal effort.

Tweet Hunter

Tweet Hunter is an AI-powered, all-in-one Twitter management tool, created to help users delete tweets, retweets, replies, and more for a fresh start on X. With its streamlined deletion interface and insights into past tweets, Tweet Hunter provides a detailed account overview for selective deletion.

Key features of Tweet Hunter:

  • Selective Deletion: Choose to delete specific types of content, such as retweets or replies, or opt for a full account cleanup;
  • Detailed Account Insights: After connecting your account, Tweet Hunter fetches data on tweet activity, giving you a comprehensive view before deleting content;
  • User-Friendly Interface: The simple interface allows for quick selection and deletion, ideal for users looking to efficiently manage their Twitter history.

Tweet Hunter’s focus on flexibility and ease of use makes it a valuable tool for anyone seeking control over their X content with the added benefit of AI-driven insights.

TweetDeleter

TweetDeleter is an effective tool for users who want to fully erase their X history, regardless of the number of posts. While Twitter’s API only allows access to the most recent 100 posts, TweetDeleter bypasses this by letting users upload their full X/Tweet Archive, making it possible to delete all posts in a single process.

Key features of TweetDeleter:

  • Full Archive Deletion: By uploading your full archive, TweetDeleter allows you to delete every single post, bypassing the 100-tweet limit imposed by the API. This is ideal for users who want a comprehensive cleanup;
  • Two Deletion Methods: Once your archive is uploaded, you can choose to either:
    • Select All and Delete: Quickly remove all posts by selecting them on your dashboard;
    • One-Click “Delete All”: Use the “Delete all X posts/tweets” feature to instantly clear your profile with a single click.
  • Effortless Process: With a simple, user-friendly interface, TweetDeleter enables you to erase your entire history with minimal steps, making the cleanup process quick and hassle-free.

TweetDeleter provides an efficient and straightforward way to remove all posts from your X account, giving you a fresh start on the platform with just a few clicks.

Reddit users have shared several methods for deleting tweets, with one of the most popular being a straightforward DIY approach. Here’s how it works:

  1. Export Your X Data: Go to Twitter’s data download page, request your data, and unzip the archive once it’s ready (this can take 1-2 days);
  1. Next, copy the bulk deletion script from this GitHub link, as shared on Reddit for efficient tweet removal;

var TweetsXer = {

    allowed_requests: [],

    dId: “exportUpload”,

    tIds: [],

    tId: “”,

    ratelimitreset: 0,

    more: ‘[data-testid=”tweet”] [aria-label=”More”][data-testid=”caret”]’,

    skip: 0,

    total: 0,

    dCount: 0,

    lastHeaders: {},

    deleteURL: ‘https://x.com/i/api/graphql/VaenaVgh5q5ih7kvyVjgtg/DeleteTweet’,

    unfavURL: ‘https://x.com/i/api/graphql/ZYKSe-w7KEslx3JhSIk5LA/UnfavoriteTweet’,

    username: ”,

    action: ”,

    bookmarksURL: ‘https://x.com/i/api/graphql/sLg287PtRrRWcUciNGFufQ/Bookmarks?’,

    bookmarks: [],

    bookmarksNext: ”,

    init() {

        // document.querySelector(‘header>div>div’).setAttribute(‘class’, ”)

        TweetsXer.username = document.location.href.split(‘/’)[3]

        this.createUploadForm()

        TweetsXer.initXHR()

    },

    sleep(ms) {

        return new Promise((resolve) => setTimeout(resolve, ms))

    },

    initXHR() {

        if (typeof AjaxMonitoring_notfired == “undefined”) { var AjaxMonitoring_notfired = false }

        if (!AjaxMonitoring_notfired) {

            AjaxMonitoring_notfired = true

            /* NOTE: XMLHttpRequest actions happen in this sequence: at first “open”[readyState=1] happens, then “setRequestHeader”, then “send”, then “open”[readyState=2] */

            var XHR_SendOriginal = XMLHttpRequest.prototype.send

            XMLHttpRequest.prototype.send = function () {

                XHR_SendOriginal.apply(this, arguments)

            }

            var XHR_OpenOriginal = XMLHttpRequest.prototype.open

            XMLHttpRequest.prototype.open = function () {

                if (arguments[1] && arguments[1].includes(“DeleteTweet”)) {

                    // POST /DeleteTweet

                    TweetsXer.deleteURL = arguments[1]

                }

                XHR_OpenOriginal.apply(this, arguments)

            }

            var XHR_SetRequestHeaderOriginal = XMLHttpRequest.prototype.setRequestHeader

            XMLHttpRequest.prototype.setRequestHeader = function (a, b) {

                TweetsXer.lastHeaders[a] = b

                XHR_SetRequestHeaderOriginal.apply(this, arguments)

            }

        }

    },

    updateProgressBar() {

        document.getElementById(‘progressbar’).setAttribute(‘value’, this.dCount)

        document.getElementById(“info”).textContent = `${this.dCount} deleted`

    },

    processFile() {

        let tn = document.getElementById(`${TweetsXer.dId}_file`)

        if (tn.files && tn.files[0]) {

            let fr = new FileReader()

            fr.onloadend = function (evt) {

                TweetsXer.skip = document.getElementById(‘skipCount’).value

                console.log(`Skipping oldest ${TweetsXer.skip} Tweets`)

                // window.YTD.tweet_headers.part0

                // window.YTD.tweets.part0

                // window.YTD.like.part0

                let cutpoint = evt.target.result.indexOf(‘= ‘)

                let filestart = evt.target.result.slice(0, cutpoint)

                let json = JSON.parse(evt.target.result.slice(cutpoint + 1))

                if (filestart.includes(‘.tweet_headers.’)) {

                    console.log(‘File contains Tweets.’)

                    TweetsXer.action = ‘untweet’

                    TweetsXer.tIds = json.map((x) => x.tweet.tweet_id)

                } else if (filestart.includes(‘.tweets.’) || filestart.includes(‘.tweet.’)) {

                    console.log(‘File contains Tweets.’)

                    TweetsXer.action = ‘untweet’

                    TweetsXer.tIds = json.map((x) => x.tweet.id_str)

                } else if (filestart.includes(‘.like.’)) {

                    console.log(‘File contains Favs.’)

                    TweetsXer.action = ‘unfav’

                    TweetsXer.tIds = json.map((x) => x.like.tweetId)

                } else {

                    console.log(‘File contain not recognized. Please use a file from the Twitter data export.’)

                }

                TweetsXer.total = TweetsXer.tIds.length

                document.getElementById(‘start’).remove()

                TweetsXer.createProgressBar()

                if (TweetsXer.action == ‘untweet’) {

                    TweetsXer.tIds.reverse()

                    TweetsXer.tIds = TweetsXer.tIds.slice(TweetsXer.skip)

                    TweetsXer.dCount = TweetsXer.skip

                    TweetsXer.tIds.reverse()

                    document.getElementById(

                        `${TweetsXer.dId}_title`

                    ).textContent = `Deleting ${TweetsXer.total} Tweets`

                    TweetsXer.deleteTweets()

                } else if (TweetsXer.action == ‘unfav’) {

                    TweetsXer.tIds = TweetsXer.tIds.slice(TweetsXer.skip)

                    TweetsXer.dCount = TweetsXer.skip

                    TweetsXer.tIds.reverse()

                    document.getElementById(

                        `${TweetsXer.dId}_title`

                    ).textContent = `Deleting ${TweetsXer.total} Favs`

                    TweetsXer.deleteFavs()

                } else {

                    document.getElementById(

                        `${TweetsXer.dId}_title`

                    ).textContent = `Please try a different file`

                }

            }

            fr.readAsText(tn.files[0])

        }

    },

    createUploadForm() {

        var h2_class = document.querySelectorAll(“h2”)[1]?.getAttribute(“class”) || “”

        var div = document.createElement(“div”)

        div.id = this.dId

        if (document.getElementById(this.dId)) { document.getElementById(this.dId).remove() }

        div.innerHTML = `<style>#${this.dId}{ z-index:99999; position: sticky; top:0px; left:0px; width:auto; margin:0 auto; padding: 20px 10%; background:#87CEFA; opacity:0.9; } #${this.dId} > *{padding:5px;}</style>

        <div>

            <h2 class=”${h2_class}” id=”${this.dId}_title”>TweetXer</h2>

            <p id=”info”>Select your tweet-headers.js from your Twitter Data Export to start the deletion of all your Tweets. </p>

        <p id=”start”>

          <input type=”file” value=”” id=”${this.dId}_file”  />

          <a href=”#” id=”toggleAdvanced”>Advanced Options</a>

          <div id=”advanced” style=”display:none”>

          <label for=”skipCount”>Enter how many Tweets to skip (useful for reruns) before selecting a file.</label>

          <input id=”skipCount” type=”number” value=”0″ />

          <p>To delete your Favs (aka Likes), select your like.js file.</p>

          <p>Instead of your tweet-headers.js file, you can use the tweets.js file. Unfaving is limited to 500 unfavs per 15 minutes.</p>

          <input id=”exportBookmarks” type=”button” value=”Export Bookmarks” />

          <p><strong>No tweet-headers.js?</strong><br>

            If you are unable to get your data export, you can use the following option.<br>

            This option is much slower and less reliable. It can remove at most 4000 Tweets per hour.<br>

            <input id=”slowDelete” type=”button” value=”Slow delete without file” />

          </p>

          </div>

        </p>

        </div>`

        document.body.insertBefore(div, document.body.firstChild)

        document.getElementById(“toggleAdvanced”).addEventListener(“click”, (() => {

            let adv = document.getElementById(‘advanced’)

            if (adv.style.display == ‘none’) {

                adv.style.display = ‘block’

            } else {

                adv.style.display = ‘none’

            }

        }))

        document.getElementById(`${this.dId}_file`).addEventListener(“change”, this.processFile, false)

        document.getElementById(“exportBookmarks”).addEventListener(“click”, this.exportBookmarks, false)

        document.getElementById(“slowDelete”).addEventListener(“click”, this.slowDelete, false)

    },

    async exportBookmarks() {

        //document.getElementById(‘exportBookmarks’).remove()

        //TweetsXer.createProgressBar()

        while (!(‘authorization’ in TweetsXer.lastHeaders)) {

            await TweetsXer.sleep(1000)

        }

        let variables = ”

        while (TweetsXer.bookmarksNext.length > 0 || TweetsXer.bookmarks.length == 0) {

            if (TweetsXer.bookmarksNext.length > 0) {

                variables = `{“count”:20,”cursor”:”${TweetsXer.bookmarksNext}”,”includePromotedContent”:true}`

            } else variables = ‘{“count”:20,”includePromotedContent”:false}’

            let response = await fetch(TweetsXer.bookmarksURL + new URLSearchParams({

                variables: variables,

                features: ‘{“graphql_timeline_v2_bookmark_timeline”:true,”responsive_web_graphql_exclude_directive_enabled”:true,”verified_phone_label_enabled”:false,”responsive_web_home_pinned_timelines_enabled”:true,”creator_subscriptions_tweet_preview_api_enabled”:true,”responsive_web_graphql_timeline_navigation_enabled”:true,”responsive_web_graphql_skip_user_profile_image_extensions_enabled”:false,”tweetypie_unmention_optimization_enabled”:true,”responsive_web_edit_tweet_api_enabled”:true,”graphql_is_translatable_rweb_tweet_is_translatable_enabled”:true,”view_counts_everywhere_api_enabled”:true,”longform_notetweets_consumption_enabled”:true,”responsive_web_twitter_article_tweet_consumption_enabled”:false,”tweet_awards_web_tipping_enabled”:false,”freedom_of_speech_not_reach_fetch_enabled”:true,”standardized_nudges_misinfo”:true,”tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled”:true,”longform_notetweets_rich_text_read_enabled”:true,”longform_notetweets_inline_media_enabled”:true,”responsive_web_media_download_video_enabled”:false,”responsive_web_enhance_cards_enabled”:false}’

            }), {

                “headers”: {

                    “accept”: “*/*”,

                    “accept-language”: ‘en-US,en;q=0.5’,

                    “authorization”: TweetsXer.lastHeaders.authorization,

                    “content-type”: “application/json”,

                    “sec-fetch-dest”: “empty”,

                    “sec-fetch-mode”: “cors”,

                    “sec-fetch-site”: “same-origin”,

                    “x-client-transaction-id”: TweetsXer.lastHeaders[‘X-Client-Transaction-Id’],

                    “x-client-uuid”: TweetsXer.lastHeaders[‘x-client-uuid’],

                    “x-csrf-token”: TweetsXer.lastHeaders[‘x-csrf-token’],

                    “x-twitter-active-user”: “yes”,

                    “x-twitter-auth-type”: “OAuth2Session”,

                    “x-twitter-client-language”: ‘en’

                },

                “referrer”: ‘https://x.com/i/bookmarks’,

                “referrerPolicy”: “strict-origin-when-cross-origin”,

                “method”: “GET”,

                “mode”: “cors”,

                “credentials”: “include”

            })

            if (response.status == 200) {

                let data = await response.json()

                data.data.bookmark_timeline_v2.timeline.instructions[0].entries.forEach((item) => {

                    if (item.entryId.includes(‘tweet’)) {

                        TweetsXer.dCount++

                        TweetsXer.bookmarks.push(item.content.itemContent.tweet_results.result)

                    } else if (item.entryId.includes(‘cursor-bottom’)) {

                        if (TweetsXer.bookmarksNext != item.content.value) {

                            TweetsXer.bookmarksNext = item.content.value

                        } else {

                            TweetsXer.bookmarksNext = ”

                        }

                    }

                })

                console.log(TweetsXer.bookmarks)

                //document.getElementById(‘progressbar’).setAttribute(‘value’, TweetsXer.dCount)

                document.getElementById(“info”).textContent = `${TweetsXer.dCount} Bookmarks collected`

            } else {

                console.log(response)

            }

            if (response.headers.get(‘x-rate-limit-remaining’) < 1) {

                console.log(‘rate limit hit’)

                let ratelimitreset = response.headers.get(‘x-rate-limit-reset’)

                let sleeptime = ratelimitreset – Math.floor(Date.now() / 1000)

                while (sleeptime > 0) {

                    sleeptime = ratelimitreset – Math.floor(Date.now() / 1000)

                    document.getElementById(“info”).textContent = `Ratelimited. Waiting ${sleeptime} seconds. ${TweetsXer.dCount} deleted.`

                    await TweetsXer.sleep(1000)

                }

            }

        }

        let download = new Blob([JSON.stringify(TweetsXer.bookmarks)], {

            type: ‘text/plain’

        })

        let bookmarksDownload = document.createElement(“a”)

        bookmarksDownload.id = ‘bookmarksDownload’

        bookmarksDownload.innerText = ‘Download’

        bookmarksDownload.href = window.URL.createObjectURL(download)

        bookmarksDownload.download = ‘twitter-bookmarks.json’

        document.getElementById(‘advanced’).appendChild(bookmarksDownload)

    },

    createProgressBar() {

        let progressbar = document.createElement(“progress”)

        progressbar.setAttribute(‘id’, “progressbar”)

        progressbar.setAttribute(‘value’, this.dCount)

        progressbar.setAttribute(‘max’, this.total)

        progressbar.setAttribute(‘style’, ‘width:100%’)

        document.getElementById(this.dId).appendChild(progressbar)

    },

    async deleteFavs() {

        // 500 unfavs per 15 Minutes

        // x-rate-limit-remaining

        // x-rate-limit-reset

        while (!(‘authorization’ in this.lastHeaders)) {

            await this.sleep(1000)

        }

        TweetsXer.username = document.location.href.split(‘/’)[3]

        while (this.tIds.length > 0) {

            this.tId = this.tIds.pop()

            let response = await fetch(this.unfavURL, {

                “headers”: {

                    “accept”: “*/*”,

                    “accept-language”: ‘en-US,en;q=0.5’,

                    “authorization”: this.lastHeaders.authorization,

                    “content-type”: “application/json”,

                    “sec-fetch-dest”: “empty”,

                    “sec-fetch-mode”: “cors”,

                    “sec-fetch-site”: “same-origin”,

                    “x-client-transaction-id”: this.lastHeaders[‘X-Client-Transaction-Id’],

                    “x-client-uuid”: this.lastHeaders[‘x-client-uuid’],

                    “x-csrf-token”: this.lastHeaders[‘x-csrf-token’],

                    “x-twitter-active-user”: “yes”,

                    “x-twitter-auth-type”: “OAuth2Session”,

                    “x-twitter-client-language”: ‘en’

                },

                “referrer”: `https://x.com/${this.username}/likes`,

                “referrerPolicy”: “strict-origin-when-cross-origin”,

                “body”: `{\”variables\”:{\”tweet_id\”:\”${this.tId}\”},\”queryId\”:\”${this.unfavURL.split(‘/’)[6]}\”}`,

                “method”: “POST”,

                “mode”: “cors”,

                “credentials”: “include”

            })

            if (response.status == 200) {

                TweetsXer.dCount++

                TweetsXer.updateProgressBar()

            } else {

                console.log(response)

            }

            if (response.headers.get(‘x-rate-limit-remaining’) < 1) {

                console.log(‘rate limit hit’)

                let ratelimitreset = response.headers.get(‘x-rate-limit-reset’)

                let sleeptime = ratelimitreset – Math.floor(Date.now() / 1000)

                while (sleeptime > 0) {

                    sleeptime = ratelimitreset – Math.floor(Date.now() / 1000)

                    document.getElementById(“info”).textContent = `Ratelimited. Waiting ${sleeptime} seconds. ${TweetsXer.dCount} deleted.`

                    await this.sleep(1000)

                }

            }

        }

    },

    async deleteTweets() {

        while (!(‘authorization’ in this.lastHeaders)) {

            await this.sleep(1000)

        }

        TweetsXer.username = document.location.href.split(‘/’)[3]

        while (this.tIds.length > 0) {

            this.tId = this.tIds.pop()

            let response = await fetch(this.deleteURL, {

                “headers”: {

                    “accept”: “*/*”,

                    “accept-language”: ‘en-US,en;q=0.5’,

                    “authorization”: this.lastHeaders.authorization,

                    “content-type”: “application/json”,

                    “sec-fetch-dest”: “empty”,

                    “sec-fetch-mode”: “cors”,

                    “sec-fetch-site”: “same-origin”,

                    “x-client-transaction-id”: this.lastHeaders[‘X-Client-Transaction-Id’],

                    “x-client-uuid”: this.lastHeaders[‘x-client-uuid’],

                    “x-csrf-token”: this.lastHeaders[‘x-csrf-token’],

                    “x-twitter-active-user”: “yes”,

                    “x-twitter-auth-type”: “OAuth2Session”,

                    “x-twitter-client-language”: ‘en’

                },

                “referrer”: `https://x.com/${this.username}/with_replies`,

                “referrerPolicy”: “strict-origin-when-cross-origin”,

                “body”: `{\”variables\”:{\”tweet_id\”:\”${this.tId}\”,\”dark_request\”:false},\”queryId\”:\”${this.deleteURL.split(‘/’)[6]}\”}`,

                “method”: “POST”,

                “mode”: “cors”,

                “credentials”: “include”

            })

            if (response.status == 200) {

                TweetsXer.dCount++

                TweetsXer.updateProgressBar()

            } else {

                console.log(response)

            }

        }

    },

    slowDelete() {

        const deleteTweets = async () => {

            document.getElementById(“toggleAdvanced”).click()

            document.getElementById(‘start’).remove()

            TweetsXer.createProgressBar()

            await new Promise(r => setTimeout(r, 200))

            try {

                document.querySelector(‘[aria-label=”Profile”]’).click()

            } catch (error) {

                document.querySelector(‘[data-testid=”AppTabBar_Home_Link”]’).click()

                await new Promise(r => setTimeout(r, 500))

                document.querySelector(‘[data-testid=”DashButton_ProfileIcon_Link”]’).click()

                await new Promise(r => setTimeout(r, 500))

                document.querySelector(‘[aria-label=”Account”] a’).click()

            }

            await new Promise(r => setTimeout(r, 2000))

            try {

                TweetsXer.total = document.querySelector(‘[aria-label=”Home timeline”]>div>div’)

                    .textContent.match(/((\d|,|\.|K)+) posts$/)[1]

                    .replace(/\.(\d+)K/, ‘$1’.padEnd(4, ‘0’))

                    .replace(‘K’, ‘000’)

                    .replace(‘,’, ”)

            } catch (error) {

                TweetsXer.total = document.querySelector(‘[data-testid=”TopNavBar”]>div>div’)

                    .textContent.match(/((\d|,|\.|K)+) posts$/)[1]

                    .replace(/\.(\d+)K/, ‘$1’.padEnd(4, ‘0’))

                    .replace(‘K’, ‘000’)

                    .replace(‘,’, ”)

            }

            let unretweet, confirmURT, caret, menu, confirmation

            const more = ‘[data-testid=”tweet”] [aria-label=”More”][data-testid=”caret”]’

            while (document.querySelectorAll(more).length > 0) {

                // give the Tweets a chance to load; increase/decrease if necessary

                // afaik the limit is 50 requests per minute

                await new Promise(r => setTimeout(r, 1200))

                // hide recommended profiles and stuff

                document.querySelectorAll(‘[aria-label=”Profile timelines”]+section [data-testid=”cellInnerDiv”]>div>div>div’).forEach(x => x.remove())

                document.querySelectorAll(‘[aria-label=”Profile timelines”]+section [data-testid=”cellInnerDiv”]>div>div>[role=”link”]’).forEach(x => x.remove())

                document.querySelector(‘[aria-label=”Profile timelines”]’).scrollIntoView({

                    ‘behavior’: ‘smooth’

                })

                // if it is a Retweet, unretweet it

                unretweet = document.querySelector(‘[data-testid=”unretweet”]’)

                if (unretweet) {

                    unretweet.click()

                    confirmURT = await waitForElemToExist(‘[data-testid=”unretweetConfirm”]’)

                    confirmURT.click()

                }

                // delete Tweet

                else {

                    caret = await waitForElemToExist(more)

                    caret.click()

                    menu = await waitForElemToExist(‘[role=”menuitem”]’)

                    if (menu.textContent.includes(‘@’)) {

                        // don’t unfollow people (because their Tweet is the reply tab)

                        caret.click()

                        document.querySelector(‘[data-testid=”tweet”]’).remove()

                    } else {

                        menu.click()

                        confirmation = await waitForElemToExist(‘[data-testid=”confirmationSheetConfirm”]’)

                        if (confirmation) confirmation.click()

                    }

                }

                TweetsXer.dCount++

                TweetsXer.updateProgressBar()

                // print to the console how many Tweets already got deleted

                // Change the 10 to how often you want an update.

                // 10 for every 10th Tweet, 1 for every Tweet, 100 for every 100th Tweet

                if (TweetsXer.dCount % 100 == 0) console.log(`${new Date().toUTCString()} Deleted ${TweetsXer.dCount} Tweets`)

            }

            console.log(‘Switching to Replies.’)

            document.querySelectorAll(‘[aria-label=”Profile timelines”]>div>div>div>div>a’)[1].click()

            await new Promise(r => setTimeout(r, 2000))

            if (document.querySelectorAll(more).length > 0) {

                deleteTweets()

            } else {

                console.log(‘Switching to Tweets.’)

                document.querySelectorAll(‘[aria-label=”Profile timelines”]>div>div>div>div>a’)[0].click()

                await new Promise(r => setTimeout(r, 2000))

                if (document.querySelectorAll(more).length > 0) {

                    deleteTweets()

                }

            }

            console.log(‘No Tweets left. Please reload to confirm.’)

        }

        deleteTweets()

    }

}

window.addEventListener(‘load’, function () {

    // necessary when used as a userscript

    const waitForElemToExist = async (selector) => {

        return new Promise(resolve => {

            if (document.querySelector(selector)) {

                return resolve(document.querySelector(selector))

            }

            const observer = new MutationObserver(() => {

                if (document.querySelector(selector)) {

                    resolve(document.querySelector(selector))

                    observer.disconnect()

                }

            })

            observer.observe(document.body, {

                subtree: true,

                childList: true,

            })

        })

    }

    TweetsXer.init()

    document.getElementById(‘exportUpload_title’).removeAttribute(‘class’)

}, false)

const waitForElemToExist = async (selector) => {

    return new Promise(resolve => {

        if (document.querySelector(selector)) {

            return resolve(document.querySelector(selector))

        }

        const observer = new MutationObserver(() => {

            if (document.querySelector(selector)) {

                resolve(document.querySelector(selector))

                observer.disconnect()

            }

        })

        observer.observe(document.body, {

            subtree: true,

            childList: true,

        })

    })

}

TweetsXer.init()

  1. Go to Twitter.com and open the browser console by pressing F12;
  2. Paste the copied script into the console and press enter. Select the tweet-headers.js file from your downloaded archive when prompted;
  3. The script will begin deleting all tweets in your account. Allow some time for the process to complete.

Key Features to Consider in Tweet Deletion Tools

When choosing a tool to delete tweets, it’s essential to focus on several important features. Selecting the right tool can save you time, ensure account security, and provide flexibility in managing your X content. Here are some key aspects to look for in a reliable tweet deletion tool:

Reliability and Security

A poorly designed tool might not function as intended and, in the worst-case scenario, could put your account at risk by triggering Twitter’s bot detection mechanisms. Choose a tool with a strong reputation to avoid account suspension or restrictions.

Control and Customization

Look for tools that offer customizable options, such as filtering tweets by date, keyword, hashtag, or tweet type (e.g., original tweets, retweets, or likes). The ability to selectively delete content can help you keep valuable tweets while removing unwanted posts.

For those who may need to restore important posts, some tools also offer ways to recover deleted tweets, giving you flexibility in managing past content before deletion.

Bulk Deletion Capability

Some tools allow you to delete thousands of tweets in a single operation, which is especially useful for accounts with a large tweet history. Ensure that the tool can handle bulk deletion if you want to clear a high volume of tweets quickly.

Scheduling and Automation

High-quality tweet deletion tools often include scheduling options that allow you to set up recurring deletions for older tweets automatically. This feature is ideal if you want to periodically clean your account by removing tweets older than a specified timeframe (e.g., tweets older than a year).

Data Privacy

Ensure that the tool respects your data privacy. Reputable tools do not store your data or require extensive permissions beyond what’s necessary to delete tweets. Always check the privacy policy to understand how your data is used.

Compatibility with Twitter’s API Limits

Twitter’s API restricts access to older tweets, typically limiting it to the most recent 3,200 tweets for third-party applications. Choose a tool that can either work within these limits or offers solutions like archive upload options for complete tweet removal.

If you’re interested in reviewing older tweets before deletion, consider tools that help you find old tweets effectively, even beyond standard API limits.

Ease of Use and User Interface

An intuitive and user-friendly interface can make a big difference, especially if you’re unfamiliar with bulk deletion tools. Look for a tool with clear instructions and a straightforward interface to make the process smooth and hassle-free.

Additional Features for Account Management

Some tools go beyond deletion, offering account management features like analytics, tweet archiving, or monitoring. While not essential for deletion, these features can provide added value, especially for brands or individuals who want comprehensive X management.

Customer Support and Documentation

A reliable tool should come with accessible customer support or a comprehensive help section. This is crucial if you encounter issues during the deletion process or if you’re new to using such tools.

Final Thoughts

Deleting all tweets can be a valuable step for those looking to manage or refresh their Twitter presence, whether for personal reputation or brand consistency. This guide has provided an overview of different methods to help you effectively remove old content and regain control over your profile. By choosing an approach that fits your needs, you can streamline your X history, reduce the risk of outdated or potentially problematic posts, and maintain a clean, professional image. With careful planning and the right strategy, clearing your Twitter history can be an easy and effective way to ensure your account reflects your current goals and values.