Pure Internet: Bluesky
2 min read
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.
- 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.
- Create an HTML file (
index.html) with your website content. - 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.
- 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 } } }'
- 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?