What I learned parsing Instagram, TikTok, X and Facebook data exports in the browser
Most "who unfollowed me" apps want your Instagram password. I wanted a tool that doesn't, so it works with the data export every platform offers instead: you download your data, drop the ZIP into a web page, and it's analyzed locally. The parsers are now open source: https://github.com/RobinOehler/unfollowtool-export-parsers
Surprising findings while parsing platform exports
-
Instagram's export format changes constantly. Since 2020 there have been at least five shapes:
- A single
connections.json -
relationships_followers - Numbered
followers_1.jsonparts - Entries where the username only lives in
title(2024) label_valuesrecords whose labels are translated into the account's language (2025)
The parser identifies fields by value shape and position, never by label.
- A single
-
Meta's JSON is mojibake by design. Every UTF-8 byte of a non-ASCII character is written as its own
\u00XXescape, so"José"arrives as"José". Decoding means re-assembling the bytes and reading them as UTF-8. -
Big ZIPs don't fit in memory. Exports that include photos easily reach several GB. Instead of loading the whole archive, the reader parses the ZIP central directory with
Blob.slice()and inflates only the follower files withDecompressionStream('deflate-raw'), including ZIP64. JSZip remains as a fallback for older browsers. -
TikTok TXT files get re-saved as UTF-16. Open
Follower.txtin Windows Notepad, click save, and it's UTF-16 with a BOM. Labels like"Username:"are also localized ("Gebruikersnaam:"), so the parser falls back to structure: the date-valued label is the date, the remaining one is the username. -
Never trust URLs from the file. X's
userLink, Facebook names, HTML anchors: all of it is untrusted input. Entries only get a profile URL that is rebuilt from a validated username or ID on the platform's own host. -
X gives you IDs, Facebook gives you names. X archives contain numeric account IDs only (no usernames, no dates); Facebook exports contain display names only. The data model has to allow
username: nulland still produce stable keys.
Implementation details
The whole thing is about 2,900 lines of dependency-free JavaScript with around 250 tests on generated fixtures. It powers https://www.unfollowtool.com/, and I'd love issue reports for export layouts it doesn't know yet.
Comments
No comments yet. Start the discussion.