Orbital SVG of your X posting scene, derived from your local birdclaw archive. No API keys. No secrets. No cloud. Just a picture of who orbits whom in your reply-graph.
The visualization answers three questions at a glance:
- Who are my closest posting-friends over the last year, by reply volume?
- Are we heating or cooling — how does my last-6-months pace compare to the steady-half of 12 months?
- Who's really in this scene — which second-layer accounts do MULTIPLE of my top-N reply to (the "shared moots" that are the connective tissue)?
Requirements
You need a birdclaw sqlite archive with authored + likes + timeline sync. Or, try it with --demo first (no DB needed).
Install
Or from source:
git clone https://github.com/responsiblparty/twitterverse cd twitterverse pip install -e .
Quickstart
Demo — no DB required:
twitterverse render --demo --output demo.html open demo.html
Against your own birdclaw DB:
twitterverse render \
--db ~/.birdclaw/birdclaw.sqlite \
--handle yourhandle \
--output my-twitterverse.htmlWith your own profile picture in the sun (birdclaw doesn't sync your own pfp — grab the URL from x.com/<yourhandle> and pass it):
twitterverse render \ --db ~/.birdclaw/birdclaw.sqlite \ --handle yourhandle \ --me-pfp 'https://pbs.twimg.com/profile_images/.../..._400x400.jpg' \ --output my-twitterverse.html
Configuration
Everything is CLI-flag-tunable, or drop a YAML config file:
twitterverse render --config example.yml --db ~/.birdclaw/birdclaw.sqlite --handle youSee example.yml for all options. The interesting knobs:
| flag | default | what |
|---|---|---|
--n-friends |
10 | how many friends form the planetary ring (5–20 works well) |
--months |
12 | window for the 12-month reply-edge total |
--months-recent |
6 | window for the trend calculation (heat/cool) |
--sun-color |
#5cd66f |
the "you" tint. Try #ff9dd8 for pink, #4dc7ff for cool blue |
--me-pfp |
— | your own profile image URL |
How it works
Reply-edge extraction. For each direction:
- Others → you uses
tweets.reply_to_id → tweets.id— reliable, because your own tweets are always in the archive. - You → others does NOT use that JOIN — parent tweets you replied to often aren't in your archive, so the JOIN drops most of your outgoing signal into an
@unknownbucket. Instead, it parses the leading@handlefrom your reply text (X convention: reply tweets literally start with@handle1 [@handle2 ...] rest), which recovers ~95%+ of outgoing edges.
If you're building on birdclaw for any social-graph project, that trick is the load-bearing insight.
Trend classification compares your 6-month reply-pace to what would be steady (half of the 12-month total):
- fire 🔥 — 6mo ≥ 130% of steady-half
- up ↑ — 110–130%
- steady → — 90–110%
- cool ↓ — 60–90%
- freeze ❄ — < 60%
Satellites are handles that at least 2 of your top-N friends reply to — they're the shared moots that make your scene coherent. Dashed lines connect a satellite to its non-primary friends.
Friend-edges (the amber curves) are direct reply-edges within the top-N. Most people's scenes have 2-4 real internal pairs — a sparse graph, meaning YOU are the bridging hub, not a member of one dense clique.
Modes
twitterverse render --demo # synthetic data preview twitterverse render --db … --handle … # full HTML page (default) twitterverse derive --db … --handle … # dump the derive() dict as JSON
Use twitterverse derive if you want to run your own analytics on top of the reply-graph without doing the SQL yourself.
Programmatic use
from twitterverse import derive, render, config data = derive.derive("~/.birdclaw/birdclaw.sqlite", "yourhandle", n_friends=15) # Custom render config cfg = config.load(sun_color="#ff9dd8", me_pfp="https://…", page_title="my scene") # Full standalone HTML page html = render.render_page(data, cfg) # Or just the SVG (embed anywhere) svg = render.render_svg(data, cfg)
Known imperfections in v0.1
- Satellite label collisions — when 2 satellites share a primary friend, or when a satellite's label sits close to a planet label, they overlap. No collision-detection yet.
- Own profile picture not synced. Birdclaw doesn't include your own pfp (you don't appear in your own profile snapshots), so
--me-pfpis required if you want your face in the sun. Falls back to the plain green disc otherwise. - DiceBear placeholder avatars for accounts that aren't in your
profilestable yet. They're deterministic per-handle so they're stable across renders.
License
MIT. Do whatever, don't sue me if birdclaw's schema changes and this breaks.
Related
- birdclaw — the local-first X archive this depends on.
