Read Your Twitter/X Archive

Turn the tweets.js file from a Twitter/X data export into a readable transcript — expanded t.co links, permalinks, per-year activity, top hashtags and your most-liked tweets — without uploading the archive anywhere.

Try:
Transcript / summary

What this tool does

Paste the tweets.js file from a Twitter/X data export and get something you can actually read: every post with its UTC timestamp, likes, retweets, language and posting app, classified as original, reply or retweet, plus a summary of how you posted over the years. The archive is parsed in your browser — nothing is uploaded, and no account or API key is involved.

The export is not JSON. data/tweets.js is a JavaScript assignment, window.YTD.tweets.part0 = [ … ], wrapping an array of {"tweet": {…}} envelopes with t.co short links, HTML-escaped text and engagement counts stored as strings. This tool strips the wrapper, expands each t.co link back to the URL the archive already stores for it, decodes the entities, and renders the result as Markdown, plain text, HTML or CSV.

Worked example

Input — a two-tweet tweets.js (an original with a shortened link, and a reply):

window.YTD.tweets.part0 = [
  {"tweet":{"id_str":"1746900000000000001","created_at":"Mon Jan 15 09:30:00 +0000 2024","full_text":"Shipped the new parser today &amp; it is fast https://t.co/abc123 #rust","favorite_count":"42","retweet_count":"7","lang":"en","source":"<a href=\"https://x.com\" rel=\"nofollow\">Twitter Web App</a>","entities":{"hashtags":[{"text":"rust"}],"urls":[{"url":"https://t.co/abc123","expanded_url":"https://example.com/parser"}]}}},
  {"tweet":{"id_str":"1746900000000000002","created_at":"Mon Jan 15 11:00:00 +0000 2024","full_text":"@bob good point, will fix","favorite_count":"3","retweet_count":"0","lang":"en","in_reply_to_screen_name":"bob"}}
]

Output — summary plus transcript, plain text, top 1 by likes:

Tweets in file: 2
Tweets after filters: 2
Tweets shown: 2 (1 original, 1 replies, 0 retweets)
Likes received: 45 (avg 22.50 per tweet)
Retweets received: 7 (avg 3.50 per tweet)
Words shown: 16
Date range: 2024-01-15 to 2024-01-15

Tweets per year:
  2024       2  100.00%

Top hashtags:
  #rust         1  50.00%

Top link domains:
  example.com       1  50.00%

Top 1 by likes:
  2024-01-15 — Shipped the new parser today & it is fast https://example.com/parser #rust  42 likes, 7 retweets  https://twitter.com/i/web/status/1746900000000000001

=== Transcript ===

[2024-01-15 11:00:00 UTC] reply · to @bob · 3 likes · 0 retweets · en
@bob good point, will fix
https://twitter.com/i/web/status/1746900000000000002

[2024-01-15 09:30:00 UTC] original · 42 likes · 7 retweets · en · Twitter Web App
Shipped the new parser today & it is fast https://example.com/parser #rust
https://twitter.com/i/web/status/1746900000000000001

Note what changed: &amp; became &, https://t.co/abc123 became https://example.com/parser, Twitter Web App was unwrapped from its HTML anchor, and each tweet gained a permalink built from its id.

Options

OptionWhat it does
OutputTweets only, summary only, or both.
FormatMarkdown (headings, tables, linked permalinks), plain text, escaped HTML you can paste into a page, or CSV rows for a spreadsheet.
Sort byNewest first (the timeline order), oldest first for a chronological read, most liked, or most retweeted.
Search textCase-insensitive substring match against the tweet text, applied after t.co links are expanded — so searching for a destination domain works.
From / To dateInclusive UTC bounds in YYYY-MM-DD form, compared against each tweet's UTC date.
Include repliesOn by default. Off keeps standalone posts and retweets only.
Include retweetsOn by default. Off keeps only what you wrote.
Expand t.co linksOn by default. Off keeps the tweet text byte-for-byte as exported.
Top tweets to listHow many most-liked tweets appear in the summary. 0 skips that table.
Max tweetsCap applied after filtering and sorting. 0 means no cap; use a small number to preview a huge archive.

Limits & edge cases

FAQ

Where do I find tweets.js?

Request your archive from Twitter/X (Settings → Your account → Download an archive), wait for the email, download the zip and extract it. The file is at data/tweets.js. Open it in a text editor and paste the whole thing — including the window.YTD.tweets.part0 = [ first line.

Is my archive uploaded anywhere?

No. The parser is Rust compiled to WebAssembly and runs inside your browser tab. There is no upload, no account, no API call and no network request carrying your tweets. The same code runs offline through the CLI.

Why are my links shortened, and how do I get the real URLs?

Twitter rewrote every outbound link to a t.co redirect, but the archive also stores the original in entities.urls[].expanded_url. With Expand t.co links on (the default) each short link is swapped for that original, and the redundant t.co link that duplicates an attached photo is removed. Turn the option off if you want the text exactly as exported.

How does it tell an original from a reply or a retweet?

A tweet is a reply if it carries in_reply_to_screen_name, in_reply_to_status_id_str or in_reply_to_user_id_str — the transcript then shows reply · to @name. It is a retweet if it carries a retweeted_status or its text begins with RT @. Everything else is an original. Replies and retweets each have their own checkbox, so you can export only what you wrote.

Can I get the data into a spreadsheet?

Yes — choose CSV rows. The transcript becomes date,id,kind,likes,retweets,language,source,text,permalink with ISO-8601 UTC timestamps, and the summary becomes section,label,value,share rows tagged summary, year, hashtag, mention, domain, source, language or top. Cells containing commas, quotes or newlines are quoted.

Can it show my most popular tweets?

Yes, two ways. The summary lists the top N most-liked tweets with their engagement and permalinks (set Top tweets to list, or 0 to hide the table). For the whole transcript in popularity order, set Sort by to most liked or most retweeted — ties break by date, then by tweet id, so the order is stable.

Does it work on an old archive, or one from a third-party tool?

Usually. Unknown fields are ignored, so newer and older export shapes both read. Engagement counts are accepted as JSON strings (what the export writes) or as numbers (what many third-party dumps write), and timestamps are accepted in Twitter's Mon Jan 15 09:30:00 +0000 2024 form or as ISO-8601. A missing field just renders as empty rather than failing the whole file.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool twitter-archive-reader 'window.YTD.tweets.part0 = [ {"tweet":{"id_str":"1746900000000000001","created_at":"Mon Jan 15 09:30:00 +0000 2024","full_text":"Shipped the new parser today","favorite_count":"42","retweet_count":"7","lang":"en"}} ]'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/twitter-archive-reader/?tweets=window.YTD.tweets.part0%20%3D%20%5B%20%7B%22tweet%22%3A%7B%22id_str%22%3A%221746900000000000001%22%2C%22created_at%22%3A%22Mon%20Jan%2015%2009%3A30%3A00%20%2B0000%202024%22%2C%22full_text%22%3A%22Shipped%20the%20new%20parser%20today%22%2C%22favorite_count%22%3A%2242%22%2C%22retweet_count%22%3A%227%22%2C%22lang%22%3A%22en%22%7D%7D%20%5D&output=both&format=markdown&sort=newest&search=parser&since=2024-01-15&until=2024-01-31&include_replies=true&include_retweets=true&expand_urls=true&top_count=5&max_tweets=0

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.