Browser console helper for tidying tweets and likes on X. You stay in control because it reuses the same GraphQL calls the site already makes.
Deleted tweets and removed likes do not return. Test with a spare account first and keep the tab focused while the script runs.
- Script lives in
main.js. - You paste it into DevTools to run it.
- You decide filters and date ranges before each run.
- Clone the repo or download the script.
- Open
main.jsin your editor. - Sign in to https://x.com in a desktop browser.
- Open DevTools → Network and capture the following from authenticated requests:
authorizationheader (Bearer token).client_tidheader (x-client-transaction-id) that matches live timeline calls.client_uuidheader. Leave it as an empty string if the header is missing.- GraphQL resource IDs:
UserTweetsAndReplies→graphQLResources.tweetsAndReplies.UserTweets→graphQLResources.tweetsOnly.Likes→random_resource_likes.
- Unlike helpers if you plan to remove likes:
UnlikeTweetquery ID →unlike_query_id.x-client-transaction-idfor the unlike call →unlike_transaction_id.
- Your handle for the
usernamefield (no leading @).
- Paste the captured values over the placeholders near the top of the file. Do not commit private tokens.
- Leave
client_uuidas""when the header is absent. - Update
delete_optionsto describe the run:- Set
from_archivetotruewhen you want to loadtweets.js. - Add pinned tweet IDs to
tweets_to_ignore. - Use
delete_specific_ids_onlyorunlike_specific_ids_onlyto target exact tweets. - Set
match_any_keywords,after_date,before_date, anddelete_message_with_url_onlyas needed. - Turn on
remove_likesonly when you also captured the unlike headers.
- Set
- Keep DevTools open on the Console tab.
- Paste your edited
main.jsinto the console. - Press Enter once to launch the workflow.
- When
from_archiveistrue, droptweets.jsinto the modal and click Confirm. - Watch the console for progress messages such as
found …,12/200, orunliked 5/20.
tweets_to_ignorewins over every other filter.match_any_keywordsis case-sensitive. Normalise inputs if needed.after_dateandbefore_dateuse your local time zone. Set both for a bounded window.delete_message_with_url_onlycombines well with keywords to target link posts.stop_signalhalts loops when the timeline returns items outside your window. Adjust the filters and run again.
- 404 responses usually mean a stale GraphQL resource ID or transaction ID. Capture fresh values from Network and rerun.
- 401 or missing cookie errors mean the session expired. Reload x.com, confirm you are logged in, and update
authorization. - Repeated 429 responses signal rate limits. Let the script wait, or split the job into smaller segments.
- Placeholders such as
"REPLACE_WITH_LIKES_RESOURCE"cause early exits. Fill them or disable the related feature.
Send pull requests when you improve the script. Follow the guidance in AGENTS.md, use Conventional Commits, and never include personal tokens.
No license is provided. Use the code only if you accept that risk.