xitter.png - privacy-friendly embeds and one-way mirrors

Hi there! The new site's up, standing on its three (mostly finished) and one (slightly wobbly) leg. I'll continue working on it and share what I've learned along the way. Enough with intros and disclaimers. This site is the Snail of Theseus after all. Let's goooooooo!

What's xitter.png

xitter.png is what I use to embed tweets on this site with respect for your privacy. By that I mean that none of the reader data is shared with the social network ad platform.

Think of it as a one-way mirror. You can see the doomsday gremlins, but the gremlins can't see you.

Why xitter.png

In short, Don't assume consent.

Slightly longer version

I don't like Twitter. The reasons are many. The one I'm tackling here is this, phrased as an edgy joke from 2003:

In Soviet Russia, Internet browses you!

(Another variant replaces Soviet Russia with Internet Explorer, but you get the picture)

Say, you're scrolling through an article listing 10 best dressed possums. You look at the embedded tweets from crème de la crème of the Didelphimorphic fashion community. You glance at a picture of a possum wearing a colander. Slowly, and quietly at first, a sense of envy crawls in on its tiny, weirdly soft, weirdly human-like paws.

Fine, you already expected to feel that way. But what you probably didn't expect is, when you gaze at a tweet, the tweet gazes back:

What happens behind the possum is akin to loading an ad widget: yes, a tweet is displayed, but also a bunch of metrics about you is sent to the parent domain, then directly or not, those metrics are shared with a bunch of third-parties.

The data can include a fingerprint of your device, cookies or anything that can be used to build a targeting profile. And that profile is then used to tell you to buy shit you don't need. This is generally achieved by finding ways to make you angry.

How it works

Short version

Nihil novi sub sole: replace Twitter embed widgets with screenshots of embeds and a link to the tweet. Tweets/screenshots are generated on my machine when the content is published.

Slightly longer version

Here's how embeds are processed and displayed normally (I split it in two parts: reader and build):


And here's how it works with xitter.png enabled:

The main difference in the second case is that most of the interactions that are normally handled when a tweet is displayed (incl. tracking) happen server-side, during build.

The code is pretty rudimentary (MISS – Make It Stupid, Simple). Here's the source.

  1. Embed tweets in Obisidian using regular links:
    ![X](https://twitter.com/xxx/status/<tweet id>)
  2. use a markdown-it plugin to transform images pointing to twitter.com as http://<xitter.url>/<tweet id>
  3. when an image is downloaded during build, xitter.png
    1. starts a web browser
    2. loads the shared tweet
    3. takes a screenshot of the tweet
    4. returns an image
  4. a screenshot of the tweet is saved in cache and added to the output

Limitations

This works surprisingly well, but only locally or at a small scale. I don't expect it to work hosted from an EC2 instance and used by hundreds of people, due to bot/scraping prevention tools used by Twitter. At the same time, I haven't tested it yet.

I did, however add basic API key support before realising I didn't need it. So, feel free to run it from the cloud and let me know how it went!

How I made it

I wrote the scaffolding with 2-3 Claude Sonnet 3.5 prompts. Then I fixed the nicely polished gibberish using a paste made of my prefrontal cortex and basic programming skills.

Reasons for this approach:

Enough training data, a relatively simple problem structure and enough personal experience to use bullshit detectors effectively makes this one of the cases where LLMs can speed up work (related LLM-powered Tools I'm Actually Using).

Why I made it

I don't share tweets that often. I probably could've just manually copy-pasted the screenshots into my notes. The reasons I'm sharing xitter.png are different from the reasons I made it:

I bought shoelaces in Shoreditch once and after I paid, the seller asked me if I could give them my email address. I think it's creepy that this attitude towards our privacy has become normalised.

If just a single person reads this and adds something similar to their site, or even considers the idea of doing so, for me that's still a win, and a real source of satisfaction.

Next steps, ideas

If you have a problem or use case for xitter.png, let me know!

What I've learned (or want to remind myself of)

express.js is (still) amazing. It's simple, intuitive, stable, it doesn't get in your way. Express is the CSS of web frameworks.

I tend to judge myself when I don't stick with a task, when I feel stuck. This is perhaps the opposite of Dog mode. Judgement or guilt are terrible ways of looking at this. It's unproductive and distracting: sometimes I need more focus, oftentimes (more than I think) I need to take a break and clear my head, and finally – sometimes I just need to distract myself with another task so I can feel that I'm moving, feel more hungry, curious.

What works better: figuring out why I'm stuck, why I feel that way. Then I can move on and act. Hummingbirds are Evil!

Thanks for reading this, see you soon!

Want to receive my work as I publish it? Subscribe here.

a giant foot-shaped snail with a house on its back. the house is still in construction, with a big crane towering above it The image is a stylized black-and-white illustration. In the lower left corner, there is a small, cozy-looking house with smoke rising from its chimney. The smoke, however, does not dissipate into the air but instead forms a dark, looming cloud. Within the cloud, the silhouette of a large, menacing face is visible, with its eyes and nose peeking through the darkness. The creature, perhaps a cat, appears to be watching over the house ominously, creating a sense of foreboding or unease.