Library / SDK
bluesky-social/atproto avatar
bluesky-social/atproto

bluesky-social/atproto: the TypeScript reference implementation behind Bluesky

Social networking technology created by Bluesky

9,665 stars926 forksTypeScriptNOASSERTION

At a glance

What is it?
The repository holds the AT Protocol Lexicon schemas, the @atproto/* npm packages, and the PDS, AppView, bsync and Ozone services. It is a protocol codebase, not an install-and-run social app, and the README says new code should prefer @atproto/lex over @atproto/api.
Who is it for?
Adopt this repository if you are implementing atproto itself, building a custom feed or bot against app.bsky.*, or adding Sign in with Bluesky, and you are willing to work with [email protected] and Node >=22. Do not adopt it if you want a turnkey social network: self-hosting a PDS is documented in the separate bluesky-social/pds repository, and the client app lives in bluesky-social/social-app.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the atproto repository actually contains

This is Bluesky's reference implementation of the Authenticated Transfer Protocol, plus the backend for the app.bsky microblogging service. The README frames the goal in terms of third-party parity: custom feeds, federated services and alternative clients are built against the same APIs, so developers are not locked out of the ecosystems they help build. That is the problem it addresses. If you want to build a client, a feed generator, a moderation tool or a full service implementation, this is the canonical source for the schemas and the TypeScript code that speaks them.

It is not a social app you install and log into. The README explicitly points elsewhere for the Bluesky client (bluesky-social/social-app) and for the Go implementation including the BGS (bluesky-social/indigo). What lives here is the protocol layer: canonically versioned Lexicon JSON schemas under ./lexicons/ for both com.atproto.* and app.bsky.*, the packages published to npm under the @atproto/* scope, and service implementations under packages/<name> with thin runtime wrappers under services/<name>.

Lexicons, XRPC and the package split

The mechanism is schema-first. Lexicon files are JSON written in a schema definition language the README compares to JSON Schema or OpenAPI. Code generation runs from those files: the Makefile's codegen target is described as re-generating packages from lexicon/ files, and the root package.json defines a codegen script that builds tooling first and then runs every codegen:* workspace script in parallel. So the schemas are the source of truth and the TypeScript types are derived artifacts.

On top of that sits XRPC, the HTTP call convention, with @atproto/xrpc as the client package and @atproto/xrpc-server on the service side. For application work the README points at @atproto/lex, described as the type-safe SDK that generates TypeScript from Lexicon schemas and provides an HTTP (XRPC) client. The rest of ./packages/lex/ holds its building blocks (data model, JSON and CBOR encoding, schema validation, server routing), which the README says you rarely need to install directly. The older @atproto/api client still exists and is still used in parts of the repo, but the README is direct that new code should prefer @atproto/lex. That is a migration signal worth reading carefully: two client surfaces are maintained, and the documentation steers you to one.

The service side is split by role. pds is the Personal Data Server that hosts repo content for atproto accounts. bsky is the AppView implementing the app.bsky.* endpoints, running on the main network at api.bsky.app. bsync is an internal synchronization service the AppView uses for cross-service state such as mutes and notifications. ozone implements the tools.ozone.* moderation API. If you are implementing the protocol rather than an application, the primitives are further split: syntax for identifier parsing, identity and did for DID and handle resolution, crypto for signing, repo for the repository and Merkle Search Tree, and sync for firehose consumption.

Installing the monorepo and running a first codegen

The root package.json pins the toolchain tightly. It declares Node >=22 in engines, requires node >=22.12.0 and pnpm 11.11.0 through devEngines with onFail set to error, and names [email protected] as the package manager. If your environment does not match, expect the install to fail rather than warn.

The Makefile documents the intended order, and its help text warns that dependencies between commands are not automatic: you must run deps and build first, and again after any changes. Start with dependencies, which uses a frozen lockfile.

bash
make deps

Then generate code from the Lexicon schemas and compile. The build target depends on codegen, so running it covers both steps.

bash
make build

The Makefile also exposes a development environment shell, which is the closest thing to a first real use of the stack locally.

bash
make run-dev-env

With logging enabled, the same target pipes output through pino-pretty.

bash
make run-dev-env-logged

For tests, the root test script sets LOG_ENABLED=false and wraps the recursive test run in ./packages/dev-infra/with-test-redis-and-db.sh, so a Redis instance and a database are part of the test harness. The README does not document what happens if those backing services are absent.

Where the reference implementation stops being the right tool

The most important limitation is stated by the README itself: the Bluesky client app is not here, and the Go implementation including the BGS is not here either. If your goal is to stand up a social network rather than to implement a protocol, you are in the wrong repository. Self-hosting directions are not in this repo at all; the README sends you to bluesky-social/pds for that.

Second, the toolchain constraints are real constraints. Node >=22.12.0 and pnpm 11.11.0 with onFail: error means older Node lines and other package managers are not supported paths. The repository is a pnpm workspace with a frozen lockfile in the documented install, so substituting npm or yarn is not a documented workflow.

Third, the codegen dependency chain adds friction. Because Lexicon schemas are canonical and packages are generated from them, changing a schema means regenerating rather than editing types by hand. The Makefile notes that command dependencies are not automatic, which means a contributor who edits lexicons and runs only a build step without codegen can end up testing stale output. There is also a dual-client situation: @atproto/api is still in use in parts of the repo while the README directs new code to @atproto/lex, so examples you find in the wild may target the older surface.

Finally, the README is a map, not a manual. It links out to atproto.com guides and specs and to GitHub Discussions for questions. The repository itself does not document operational rollback, migration between client packages, or capacity planning for the services.

atproto versus ActivityPub and the fediverse

The comparison people reach for is ActivityPub, the protocol behind Mastodon and much of the fediverse. The architectural difference visible in this repository is where identity and data live. Here, a Personal Data Server hosts repo content for an account, and the AppView is a separate service that indexes and serves the app.bsky.* endpoints. The repository and Merkle Search Tree work lives in its own package, and firehose consumption is its own package, which tells you the design expects independent services to consume a stream of repository changes rather than each server holding a full copy of everyone's posts.

ActivityPub implementations more commonly treat each server as both the home of its users' content and the point of federation for it. That shapes operations: in the atproto model you can run a PDS without running an AppView, and the AppView can be replaced by an alternative indexer. The trade-off is more moving parts and more protocol surface to implement. The README lists pds, bsky, bsync and ozone as distinct services, and bsync exists purely to synchronize cross-service state such as mutes and notifications, which is a concrete example of the coordination cost this architecture accepts.

If you want the smallest possible path to a federated timeline and you are comfortable with the ActivityPub ecosystem, the atproto stack is more machinery than you need. If you want account portability with a data repository that other services can index independently, the split is the point.

Licence, patent posture and the cost of tracking upgrades

The README states the project is dual-licensed under MIT and Apache 2.0, with LICENSE-MIT.txt and LICENSE-APACHE.txt at the repository root. Downstream projects and end users may choose either licence individually or both together, at their discretion. The stated motivation for dual licensing is the additional software patent assurance provided by Apache 2.0, and the README notes that Bluesky Social PBC has committed to a software patent non-aggression pledge. The root package.json lists the license field as MIT while the repository metadata reports NOASSERTION, so if licence terms matter to your review process, read the two licence files rather than relying on metadata fields.

Upgrade cost is shaped by the release cadence and the workspace layout. Recent releases include @atproto/[email protected], @atproto/[email protected] and @atproto/[email protected], all dated 2026-09-11, and the last push to the repository was on 2026-09-21. Packages are versioned independently under the @atproto/* scope, so you upgrade per package rather than as one monolith, and minor-version drift between the client and server packages is something to check when you pin. The internal utilities under ./packages/internal/ use a different scope, @atproto-labs/*, which is worth knowing before you assume every dependency in the tree is a supported public package. The README does not publish a support window or a deprecation schedule for @atproto/api.

Editorial conclusion

Adopt this repository if you are implementing atproto itself, building a custom feed or bot against app.bsky.*, or adding Sign in with Bluesky, and you are willing to work with [email protected] and Node >=22. Do not adopt it if you want a turnkey social network: self-hosting a PDS is documented in the separate bluesky-social/pds repository, and the client app lives in bluesky-social/social-app. Before committing, verify which client you are starting from, since the README states new code should prefer @atproto/lex while @atproto/api still exists and is still used in parts of the repo.

Frequently asked questions

What is the AT Protocol?

The README describes it as the Authenticated Transfer Protocol, a decentralized social media protocol developed by Bluesky Social PBC. This repository is Bluesky's TypeScript reference implementation of it, plus the backend for the app.bsky microblogging service.

Who created ATProto?

The README attributes it to Bluesky Social PBC, which also maintains the software patent non-aggression pledge mentioned in the licence section. The repository author field lists Bluesky Social PBC as well.

Is atproto open source?

Yes. The README states the project is dual-licensed under MIT and Apache 2.0, with LICENSE-MIT.txt and LICENSE-APACHE.txt in the repository, and downstream users may choose either licence or both.

What is a PDS in atproto?

The README defines pds as the Personal Data Server, which hosts repo content for atproto accounts. It notes that directions for self-hosting one live in the separate bluesky-social/pds repository, not in this one.

What are the key differences between ActivityPub and ATProto?

This repository does not draw that comparison directly. What it does show is a split between the Personal Data Server that hosts repo content and the AppView that serves app.bsky.* endpoints, with bsync synchronizing cross-service state and sync providing firehose consumption.

Official sources

  1. bluesky-social/atproto on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bluesky-social-atproto.svg)](https://hysenlabs.com/projects/bluesky-social-atproto)