# Murmuration

Sleek WebGL explorer for visualizing your X activity over time.

Canonical URL: https://www.transitivebullsh.it/projects/murmuration

Author: Travis Fischer

Published: 2026-10-22

Updated: 2026-10-21T20:32:00.000Z

Tags: OSS, Projects, Twitter, React.js

[Website](<https://murmuration.transitivebullsh.it>)

[Source](<https://github.com/transitive-bullshit/murmuration>)

[Original post](<https://x.com/transitive_bs/status/2112985285499944963>)

![Murmuration](<https://assets.cultural-alignment.com/personal-site/media/488d0e3939370fb065debc928574ba5b2d19b536a69930793a923a06e661e8d4.jpg>)

[Watch video](<https://www.youtube.com/watch?v=s_BR5InETV8>)

Demo video: a quick tour through all six views on the live site.

---

<a id="a4e15817f8f04c61ba7a8bd5caec0467"></a>

## Why I built this

I've been posting on X / Twitter since 2011: 11.6k tweets, 36.7k likes, and an audience that slowly grew to about 21k followers. That history is a surprisingly honest record of what I was obsessed with, what actually landed, and who I was really talking to. But X gives you no good way to look at any of it. Your archive is a zip file full of JSON.

Then I saw [@azlenelza searching through their Twitter likes](<https://x.com/azlenelza/status/2112305483692532123>) under the caption *"Data just feels malleable lately"*, and it clicked. My whole archive already lived in a local SQLite database thanks to [Birdclaw](<https://github.com/steipete/birdclaw>). So what would it feel like to actually *explore* fifteen years of posting?

I had a few questions that no amount of scrolling could answer:

- What do I actually talk about, and how has that drifted over the years?
- Which kinds of tweets land, and has that changed?
- Why did my follower count jump when it did?
- Who am I actually close to, as opposed to who I just follow?

<a id="28857a88825b416e890a631b539a54b5"></a>

## Six views, one flock

![Constellation: every tweet and like placed by meaning, with labeled topics.](<https://assets.cultural-alignment.com/personal-site/media/a27681652f33f3298125018a71eacfe9a671f3b4583e67cb3dc1cc11d88008f0.webp>)

Constellation: every tweet and like placed by meaning, with labeled topics.

Murmuration turns the archive into about 48k particles, one per tweet or like, which flock between six views as you switch tabs. (Hence the name: a murmuration is a flock of starlings moving as one.)

- **Constellation** places every tweet and like by meaning, so topics show up as labeled nebulae, and it tells you which topics your tweets land best in.
- **Growth** plots your follower curve above the engagement of every tweet. Click an inflection point to see the tweets most likely to have caused it.
- **Bangers** lines up your biggest hits and outliers on a timeline, each one a click away.
- **Strata** stacks your timeline month by month, colored by topic, so you can see what you were thinking about each year.
- **Anatomy** breaks down which kinds of tweets perform best by format, topic, day, hour and length, and how that changed year by year.
- **Orbit** arranges your followers and the people you follow around you, with the people you actually talk with closest in. Press play to watch your audience accrete over time.

![Growth: the January 2023 surge, traced back to the tweets most likely to have caused it.](<https://assets.cultural-alignment.com/personal-site/media/788985b9eec900609a16e967caf42eba4848975939e37244fa71970f2d283270.webp>)

Growth: the January 2023 surge, traced back to the tweets most likely to have caused it.

![Strata: tweets and likes stacked month by month, colored by topic.](<https://assets.cultural-alignment.com/personal-site/media/4d4beb89e84511e4854ef00cfb74587f583f087b74175d9f22c19da84f549d0a.webp>)

Strata: tweets and likes stacked month by month, colored by topic.

![Anatomy: which kinds of tweets perform best.](<https://assets.cultural-alignment.com/personal-site/media/23e1e0ad9aaf68f9e2d11d5ea00c9ecbc95929187629304ddf3b5e816804fc16.webp>)

Anatomy: which kinds of tweets perform best.

![Orbit: followers and following, with my closest relationships nearest the center.](<https://assets.cultural-alignment.com/personal-site/media/b0a23295a27d81f956ebf0085fe0bab4688b831eac2fce5afe546d9407979c87.webp>)

Orbit: followers and following, with my closest relationships nearest the center.

<a id="5aeb1bd384ec4c6e88a87a818a80b4f5"></a>

## How I built it

I built Murmuration with Claude Code + Opus 5.5 over two days.

A few decisions shaped how it works.

- **Topics needed real embeddings.** The first version clustered tweets with classic word statistics (TF-IDF and LSA). Switching to OpenAI embeddings imroved things, and captioning every image with a vision model means screenshots and memes cluster by what's actually in them. Both are cached per tweet, so it's a one-time cost and later builds only pay for what's new. Without an API key, it falls back to a small local model and then to word statistics.
- **Your archive doesn't know when anyone followed you.** X's export lists your followers, but not when they followed. It turns out the list is roughly newest-first, in blocks, and X's account IDs encode when each account was created. An account can't follow you before it exists, so the newest account seen so far bounds when each follow happened, and interpolating between those gives a believable follower curve. Growth and Orbit are built on it.
- **A growth spike isn’t always attributable to X activity directly.** Growth attributes each inflection point to the tweets most likely to have caused it, based on timing and engagement. When nothing I posted can explain a jump, it says so and flags the boost as coming from somewhere else.
- **Close means mutual.** Orbit ranks people by two-way engagement. Mutual replies and likes count far more than one-sided attention, and recent interactions count more than old ones.
- **Local first, then a static snapshot.** Everything runs on your machine and reads the Birdclaw database strictly read-only. To share it, one command exports a static snapshot with every DM's text stripped out (only counts survive) and uploads it. There's no server or database in production, and the dataset never touches git.

<a id="3f162e89c7954c2d8511b3d823ee2792"></a>

## Try it on your own archive

Like [Reading Room](<https://www.transitivebullsh.it/projects/reading-room>) did for my Goodreads shelf, Murmuration turns a personal data export into a place you can actually wander around.

It's free and [open source](<https://github.com/transitive-bullshit/murmuration>). Import your X archive with Birdclaw, run ` pnpm install && pnpm dev `, and it opens on your own history. Or [explore mine first](<https://murmuration.transitivebullsh.it/>) && I'd love to hear what you find in yours!
