npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dwk/atproto-pds

v1.0.0-beta.2

Published

Edge-native AT Protocol Personal Data Server: XRPC surface, signed Merkle Search Tree repository, CAR sync, did:web identity. Ships the per-account Durable Object.

Readme

@dwk/atproto-pds

Edge-native AT Protocol Personal Data Server: XRPC surface, a signed Merkle Search Tree repository, CAR sync, and did:web identity. Endpoint package + Durable Object.

Part of the @dwk IndieWeb + Solid cohort. See the package specification for the full requirements — including why this package is the cohort's strategic outlier.

A self-hosted AT Protocol Personal Data Server (PDS) rooted at the user's own domain: the home of one account's repository in the Bluesky network. It is the package embodiment of “there are no instances in atproto” — identity is a did:web the user controls and hosting is a swappable service entry in that DID document, so the repository is a portable, signed, content-addressed structure rather than an identity-defining silo. It mirrors the architecture proven in @dwk/solid-pod: a stateless front door over a per-account Durable Object that is the single authority for the repository signing key, the MST, and the signed commit chain.

Unlike the rest of the cohort it shares neither @dwk/store (the repository is an MST/blockstore, not key → { rdf | blob }) nor @dwk/rdf (records are lexicon-typed DAG-CBOR, not RDF), so its storage core — DAG-CBOR, CIDv1, the MST, CAR, and commit signing — is self-contained and built directly on WebCrypto.

What it covers

  • Identity at your own domain/.well-known/atproto-did (handle → DID) and /.well-known/did.json (a did:web document advertising the repository signing key as a Multikey and the PDS as an AtprotoPersonalDataServer service).
  • XRPC surface (/xrpc/<nsid>):
    • com.atproto.server.*createSession, getSession, refreshSession, describeServer.
    • com.atproto.repo.*createRecord, putRecord, deleteRecord, getRecord, listRecords, describeRepo, uploadBlob.
    • com.atproto.sync.*getRepo (CAR export), getLatestCommit, getBlob, listRepos.
    • com.atproto.identity.resolveHandle.
  • A signed, portable repository — records are DAG-CBOR blocks in a deterministic Merkle Search Tree; each write produces a new commit signed with the account's repository key (compact, low-S) and chained through prev. getRepo exports the whole thing as a CARv1 whose root commit verifies against the key in the DID document.
  • Blobs stream to R2, addressed by their raw-codec CID.

Design decisions

  • P-256 signing by default, secp256k1 (K-256) opt-in. Both are valid per AT Protocol's cryptography spec. WebCrypto supports P-256 natively, so it is the dependency-free default (published as a did:key, multicodec 0x1200). Set signingCurve: "secp256k1" for the network-preferred curve real Bluesky accounts use — signed via @noble/curves (deterministic, low-S) and published with multicodec 0xe7. The curve is fixed at repository genesis.
  • did:web by default, did:plc opt-in (in progress). did:web keeps identity on the user's own origin with no external PLC directory. Set didMethod: "plc" for a did:plc account: the DO mints a DO-custodied rotation key, self-signs a genesis operation, derives its did:plc, and serves it consistently. The PLC directory client (plc-directory.ts) submits the genesis op (POST /:did) and resolves DIDs (GET /:did); set plcDirectoryUrl to register a fresh account on the network at creation — done via a Durable Object alarm with exponential-backoff retry, never blocking init (default unset — nothing reaches the network unless asked).
  • Single-account scope. One account per baseUrl, authenticated by a configured password. The firehose is future work.

Usage

import { createAtprotoPds, AtprotoRepoObject } from "@dwk/atproto-pds";

const pds = createAtprotoPds({
  baseUrl: "https://alice.example.com",
  password: env.ACCOUNT_PASSWORD, // secret binding
  jwtSecret: env.SESSION_SECRET, // secret binding
});

export default {
  fetch: (request, env, ctx) => pds(request, env, ctx),
};

export { AtprotoRepoObject };

The composed Worker must bind the REPO Durable Object namespace (AtprotoRepoObject) and the BLOBS R2 bucket; a missing binding fails loudly at startup.

License

ISC