How it works
From one post
to the whole network.
Bluesky runs on the AT Protocol: an open network where every app reads and writes the same public data. Here's how individually addressable records combine to form the network you can build on.
A post is just a record
Every account on the network has its own public data repository. When someone posts on Bluesky, the app writes a small JSON record into their repo.
It's addressable through an at:// URI, and anyone can fetch it.
{ "$type": "app.bsky.feed.post", ← a Lexicon name "text": "Oh yeah I know Jimothy. Went to high school with him. Weird guy. Loved trash", "langs": ["en"], "createdAt": "2026-07-18T06:41:53.927Z"}
The $type names a Lexicon
app.bsky.feed.post is one type of record, identified by a reversed domain name. Whoever owns the domain can publish a Lexicon: a schema that says what records of that type look like. Bluesky defines the app.bsky.* types, and other apps define their own. All of them live in the same repos, on the same network.
Lexicons are the protocol's schema language — the full story lives at atproto.com.
Every record flows through one stream
Repositories sync to relays, which merge everything happening on the network into a single firehose. Jetstream — one of the services Bluesky operates — serves it as plain JSON over a WebSocket. This is the live network, right now:
Filter by Lexicon, get your slice
Every Lexicon type is a collection you can filter by. Ask for one collection, and the server sends only those records, already decoded and typed.
This is every blog post published anywhere on the network, as it happens, in fewer than 10 lines.
import { Jetstream } from '@bsky/jetstream' const jetstream = new Jetstream('https://jetstream.us-east.bsky.network') for await (const evt of jetstream.live({ collections: ['site.standard.document'] })) { if (evt.kind === 'commit' && evt.commit.operation === 'create') { console.log(`📝 ${evt.did} published "${evt.commit.record.title}"`) }}
An app is a lens on the network
That is how apps get built here: pick the Lexicons you care about, index those records into a view, and serve it. A new app doesn't launch empty since it seeds its view from the open network.
Each of these is a different lens over the same accounts, the same repositories, the same open network, focused on its own slice of Lexicons. And every record they index or write stays open for the next app to build on, including yours.



