home menu

Pure Internet: Bluesky

Exploring non-standard web hosting via Bluesky's AT Protocol, a content-addressable system similar to IPFS that can serve as a minimalist.

After NFC cards with data URLs and ENS+IPFS, I got a static site running on Bluesky's AT Protocol. This experiment was inspired by Daniel Mangum's exploration of atproto's storage capabilities.

Bluesky is mostly known as a social platform. The AT Protocol underneath is a content-addressable system with built-in distribution. Every blob gets a CID, retrievable through any AT Proto node. It's IPFS in different clothes.

If you can upload arbitrary blobs and get stable URLs back, you can use it as web hosting. Here's the recipe.

  1. First, create a session with your Bluesky credentials:
curl -X POST 'https://bsky.social/xrpc/com.atproto.server.createSession' \ -H 'Content-Type: application/json' \ -d '{"identifier": "your-handle.bsky.social", "password": "your-password"}'

Save the accessJwt from the response for the next steps.

  1. Create an HTML file (index.html) with your website content.
  2. Upload your HTML file as a blob:
curl -X POST 'https://bsky.social/xrpc/com.atproto.repo.uploadBlob' \ -H 'Authorization: Bearer YOUR_ACCESS_JWT' \ -H 'Content-Type: text/html' \ --data-binary '@index.html'

The response will include a blob reference with a CID. Save this CID for the next step.

  1. Create a record referencing your blob:
curl -X POST 'https://bsky.social/xrpc/com.atproto.repo.createRecord' \ -H 'Authorization: Bearer YOUR_ACCESS_JWT' \ -H 'Content-Type: application/json' \ -d '{ "repo": "your-handle.bsky.social", "collection": "com.yourdomain.website", "record": { "$type": "com.yourdomain.website", "website": { "$type": "blob", "ref": { "$link": "YOUR_BLOB_CID" }, "mimeType": "text/html", "size": YOUR_FILE_SIZE } } }'
  1. Get the URL of your website:
curl -I 'https://bsky.social/xrpc/com.atproto.sync.getBlob?did=YOUR_DID&cid=YOUR_BLOB_CID'

The response includes a location header with your website's permanent URL. Here's a real example:

https://amanita.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did:plc:p5xem22ammiafn5kxonaksfa&cid=bafkreih2pbifus4ed6p7kfuqjbjbqmzewlnyaz7f7ykmk5bvchkj7w3eb4

The URL parts: amanita.us-east.host.bsky.network is a Bluesky content delivery node, com.atproto.sync.getBlob is the retrieval endpoint, did is the content owner, cid is the content hash.

The trade-offs are real. You depend on Bluesky's infrastructure. Blobs have size caps. The platform isn't built for static hosting, so content could disappear. The setup is just dead simple.

It's not pure internet in the sovereign sense, since the federation still owns the delivery. But it leaves a question hanging: how far can a social protocol stretch before it becomes a general-purpose CDN?

collection
posts
rkey
1732585567703-pure-internet-bluesky
record cid
bafkreihvrbruc3qw4gcl64e26vyjzy4ndcnmfk47bjjrotjfoc6jqi2kiu
record
https://content.farfield.systems/api/entries/1732585567703-pure-internet-bluesky
created
updated