Dev.to WebDev πŸ›  Dev πŸ‘ 1 πŸ“– 3 min read

How I Built a 100% In-Browser Instagram Chat Analyzer (Zero Cloud Uploads)

Direct messages contain our most intimate conversations, jokes, memories, and photos. Yet, when searching for tools to visualize chat history or generate Spotify Wrapped-style stats for group chats, virtually every exist

Direct messages contain our most intimate conversations, jokes, memories, and photos. Yet, when searching for tools to visualize chat history or generate Spotify Wrapped-style stats for group chats, virtually every existing tool asks for your Instagram login or forces you to upload your sensitive ZIP archives to their cloud servers.

I wanted to change that. I built Stats Insta β€” a completely free, 100% client-side Instagram Chat Analyzer where your data never leaves your device.

In this article, I will share the engineering challenges behind parsing multi-megabyte JSON exports in the browser, decoding escaped Unicode emojis, computing deep conversational metrics, and generating 9:16 Instagram Story cards directly from the DOM.

πŸ”’ The Architecture: 100% Client-Side Privacy

The core philosophy behind Stats Insta is Local-First Processing:

  1. Zero Server Uploads: The application does not have a backend parsing server or database for chat messages.
  2. Native HTML5 FileReader: When a user drops a message_1.json file, the browser reads the file directly into client-side RAM using FileReader.readAsText().
  3. Session-Only Memory: Once you refresh or close the browser tab, the data is instantly garbage-collected by the browser engine.

You can verify this in Chrome DevTools (F12 > Network Tab): dropping a 50MB conversation file triggers 0 network POST requests.

βš™οΈ Technical Challenge 1: Decoding Instagram's Unicode Escapes

When Meta exports your message history in JSON format, emojis and special characters are not stored as standard UTF-8 strings. Instead, they are encoded as escaped byte sequences (e.g., \u00e2\u009d\u00a4 for a red heart).

If rendered directly in React, emojis appear as garbled characters (Mojibake). To resolve this, I implemented an in-memory Unicode normalization pipeline:

const decodeUnicode = (unicodeString: string): string => {
  try {
    return decodeURIComponent(
      unicodeString.replace(/\\u([0-9a-fA-F]{4})/g, "%u$1")
    );
  } catch (error) {
    return unicodeString;
  }
};

This converts raw escaped sequences into native browser-rendered emojis at runtime without lagging the main thread.

πŸ“Š Technical Challenge 2: Calculating Deep Conversational Metrics

Simple message counts are boring. People care about the hidden dynamics of their friendships. We compute several unique behavioral metrics in browser memory:

1. The "Night Owls" Tracker (12:00 AM – 4:59 AM)

We parse the Unix millisecond timestamps (timestamp_ms) on each message and isolate activity occurring in the late-night window:

const hour = new Date(msg.timestamp_ms).getHours();
if (hour >= 0 && hour <= 4) {
  nightOwlCounts[msg.sender_name] = (nightOwlCounts[msg.sender_name] || 0) + 1;
}

This immediately reveals who stays awake sending reels and memes while everyone else is asleep.

2. The Conversation Starter Algorithm

Who puts in the effort to keep the conversation alive? We sort the timeline chronologically and scan for silence gaps exceeding 12 hours:

const TWELVE_HOURS_MS = 12 * 60 * 60 * 1000;
if (lastTimestamp === 0 || msg.timestamp_ms - lastTimestamp > TWELVE_HOURS_MS) {
  starterCounts[msg.sender_name] = (starterCounts[msg.sender_name] || 0) + 1;
}
lastTimestamp = msg.timestamp_ms;

3. The Swear Jar

We scan message strings against a local tokenized dictionary of 100+ global curse words and slang to generate a friendly group chat leaderboard of who has the dirtiest mouth.

πŸ“± Technical Challenge 3: Generating 9:16 Instagram Story Wrapped Cards

People love sharing aesthetic visual summaries with their friends. To make the tool virally shareable, I built an in-browser Story Card generator that renders a 1080x1920 (9:16 Full HD) graphic using HTML5 Canvas:

  • Glassmorphism gradient backgrounds with radial glowing orbs
  • Rounded progress bars showing conversational dominance percentages
  • Dynamic badges and highlights
  • 1-Click Native Share: On mobile devices, we invoke the Web Share API (navigator.share({ files: [pngFile] })), which opens the native iOS/Android share sheet directly into Instagram Stories!

πŸš€ Try It Live & Explore the Code

The project is completely free to use, and I have published detailed guides on understanding Meta's export architecture:

I would love to hear feedback from the DEV community! What other client-side analytics or visual metrics would you like to see added?

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.