Eighteen crates, shelved by layer. Plate marks run A at the data foundation to G at the tooling edge; within a band the order is the order you would reach for them.
§ 00
Reading the status column
Published version and workspace version are not the same number, and three crates have no published version at all. Every entry states both.
Status marks used in this catalogue
Mark
Means
How you depend on it
Published
On crates.io at 0.14.5. The git workspace is ahead at 0.15.0-rc.2, unpublished.
name = "0.14.5"
Git only
Never published to crates.io.
name = { git = "https://tangled.org/ngerakines.me/atproto-crates" }
Experimental
The crate says so itself, in its own README. Interfaces and on-disk formats will move.
Pin a revision.
A
Data foundation
Content addressing and the byte formats everything else is expressed in.
The DASL implementation the rest of the workspace is built on. Nine modules: cid (three CID types — general, strictly-validated DaslCid, and unvalidated RawCid), drisl (deterministic DAG-CBOR with sorted keys, shortest-form integers, NaN and infinity rejected), car (streaming CAR v1 reader and writer with size and depth limits), storage (block-store trait with memory and disk backends, plus spillover), bdasl (BLAKE3/BAO for large files), masl, rasl, tiles, and varint.
Multi-method DID resolution for did:plc, did:web and did:key; handle resolution over both DNS TXT and the HTTPS well-known endpoint, with conflict detection when the two disagree; P-256, P-384 and K-256 key generation, signing and validation; LRU-cached DID document storage behind a pluggable trait. It also carries the PLC directory client, including an audit-log reader and a fork visualiser.
The small, unglamorous pieces every record touches: parsing and validating at:// URIs, generating microsecond-precision TIDs, RFC 3339 datetimes with the millisecond precision AT Protocol expects, base64 handling for binary fields, and typed records with lexicon $type validation. CID generation here goes through DAG-CBOR and SHA-256.
Creates and verifies record attestations using the CID-first workflow: prepare the record with $sig metadata, serialise to DAG-CBOR, hash to a CID, sign the CID bytes, then either embed the signature (inline) or emit a separate proof record holding a strongRef (remote). Signatures are normalised to low-S form so they cannot be malleated. The repository field inside $sig binds an attestation to one repo, which is what stops a record being lifted into somebody else’s.
Implements the full resolution chain: NSID to a _lexicon.-prefixed DNS name, TXT lookup for the authoritative DID, DID document resolution, PDS endpoint extraction, then the XRPC fetch of the schema itself. Resolves referenced lexicons recursively with a depth limit, handles fragment-only references using the enclosing lexicon as context, and validates NSIDs on the way in.
MST insert, get, delete, list and diff, with SHA-256 key-height calculation; AT Protocol commit structures with serialisation and validation; record path handling for collection/rkey; and CAR v1 reading and writing built on atproto-dasl. Storage is pluggable: in-memory with LRU eviction, disk-backed with a memory cache, and a spillable buffer for streaming large archives. Verification depth is configurable, so you can pay for full inductive verification or skip it.
Primitives for the 0016 Permissioned Data draft: the SetHash trait with LtHash as the production lattice hash, signed commits that sign only the per-commit context and bind the set-hash digest through an HKDF-keyed HMAC, so a leaked commit stays deniable, a SpaceRepo orchestrator for per-(user, space) record CRUD, and the two-step delegation-token to space-credential JWT exchange.
The whole client flow: PAR, PKCE, DPoP, JWT, scopes
The OAuth crate, and since the removal of atproto-oauth-aip the only one you need for a client. Ten modules. workflow drives the flow end to end — oauth_init pushes the authorization request and returns a request_uri, oauth_complete exchanges the code, oauth_refresh rotates the token. Underneath: JWT minting and verification across ES256, ES384 and ES256K; JWK generation for all three curves; PKCE per RFC 7636; DPoP per RFC 9449; resources for RFC 8414 discovery; and scopes, a typed parser for the AT Protocol scope grammar. Request storage is a trait with an LRU implementation behind the lru feature.
The routes a confidential client has to publish anyway: the authorization callback, the JWKS endpoint, and client metadata. Drop them into an existing Axum router rather than re-deriving the JSON shapes from the specification.
Components, hooks and server functions that carry the OAuth flow through a Dioxus fullstack application. The only crate directory that is not a workspace member. It is versioned at 0.15.0-alpha.2 and built on its own.
XRPC over reqwest with three authentication modes (DPoP-bound tokens, app-password bearer tokens, and classic sessions), plus typed repository operations under com::atproto::repo (create_record, put_record, and friends), session creation and refresh, and URL construction helpers that get the /xrpc/ prefixing right.
The server counterpart. An Authorization Axum extractor validates an inter-service JWT, resolves the issuer’s DID document, and verifies the signature against the key published there — so a handler receives a caller identity that has actually been proven, or None. No binaries of its own; atproto-pds is the worked example now that the hello-world service has been removed.
A full PDS: the pds server binary and the atproto-pds-admin CLI. It serves com.atproto.repo.*, sync.* (including subscribeRepos and CAR streaming with ?since= diff slices), server.*, identity.*, admin.*, a complete OAuth 2.1 provider, and the simplespace/space permissioned realms. It is the second PDS implementation anywhere to ship Spaces, and the first in Rust. Two storage profiles, SQLite and fjall, chosen at compile time.
Consumes the JSON firehose: WebSocket streaming with automatic reconnection, Zstandard decompression against Bluesky’s published dictionary, filtering by collection and DID, and a handler-registration model that lets several processors share one connection. Shutdown runs through a CancellationToken, so a consumer drains rather than drops.
Streams from a TAP service, which delivers events already MST-verified and signature-checked. Adds at-least-once delivery through an acknowledgment protocol that survives reconnects, exponential backoff, historical backfill flagged live: false, and an HTTP management API for adding and removing tracked DIDs. Events are Arc-wrapped and small strings are CompactString, because the working set is the whole point.
Extracts mentions, URLs and hashtags from plain text and emits facets with correct UTF-8 byte offsets. Implementations written against character indices get this wrong. Optionally resolves mention handles to DIDs during the parse.
A local Model Context Protocol server speaking JSON-RPC 2.0 over stdio. It exposes one tool, create_record_cid, which takes a JSON record, serialises it deterministically to DAG-CBOR, hashes it, and returns the CIDv1 string — so an assistant can compute a real content identifier instead of guessing at one.
Two crates were dropped in b8ff044. Both are still resolvable on crates.io at 0.14.5, so a build that depends on them keeps working — it is just building against code that no longer exists upstream and will not be released again.
What went, and what to use instead
Crate
Was
Replacement
atproto-oauth-aip
The workflow layer above atproto-oauth: oauth_init, oauth_complete, session_exchange.
atproto-oauth, module workflow. oauth_init and oauth_complete live there now, alongside a new oauth_refresh. There is no session_exchange — see the rewritten guide.
atproto-xrpcs-helloworld
A runnable example service demonstrating did:web identity, service documents and JWT auth.
No direct replacement. atproto-pds is the worked example of an XRPC service built on atproto-xrpcs, at considerably larger scale.