A zero-dependency AT Protocol Personal Data Server written in JavaScript
atproto pds
1# pds.js 2 3A zero-dependency AT Protocol Personal Data Server written in JavaScript, running on Cloudflare Workers with Durable Objects. Let's see how far we can get with just Web APIs. 4 5> ⚠️ **Work in progress** - This is experimental. You probably shouldn't use this yet. 6 7## Status 8 9- [x] Repo operations (createRecord, getRecord, putRecord, deleteRecord, applyWrites, listRecords) 10- [x] Sync endpoints (getRepo, getRecord, subscribeRepos, listRepos, getLatestCommit) 11- [x] Auth (createSession, getSession, refreshSession) 12- [x] Handle resolution (resolveHandle) 13- [x] AppView proxy (app.bsky.* forwarding with service auth) 14- [x] Relay notification (requestCrawl) 15- [x] Single or multi-user (each DID gets isolated storage, no self-service signup yet) 16- [x] Blob storage (uploadBlob, getBlob, listBlobs) 17- [ ] deleteSession (logout) 18- [ ] updateHandle 19- [ ] importRepo 20- [ ] OAuth 21- [ ] Account management (createAccount, deleteAccount) 22- [ ] Email verification 23- [ ] Invite codes 24- [ ] Admin/moderation 25- [ ] Rate limiting 26 27## Prerequisites 28 29- Node.js 18+ 30- [shfmt](https://github.com/mvdan/sh) (optional, for `npm run format`) 31 ```bash 32 brew install shfmt 33 ``` 34 35## Quick Start 36 37```bash 38npm install 39 40# Create local dev config 41cp .env.example .dev.vars 42# Edit .dev.vars with your values 43 44# Run locally 45npm run dev 46``` 47 48## Configuration 49 50For local development, create `.dev.vars`: 51 52``` 53PDS_PASSWORD=your-password 54JWT_SECRET=your-secret 55RELAY_HOST=https://bsky.network # optional 56``` 57 58For production, use Cloudflare secrets: 59 60```bash 61wrangler secret put PDS_PASSWORD 62wrangler secret put JWT_SECRET 63wrangler secret put RELAY_HOST # optional 64``` 65 66### Blob Storage 67 68Blobs (images, videos) are stored in Cloudflare R2. Create the bucket before deploying: 69 70```bash 71npx wrangler r2 bucket create pds-blobs 72``` 73 74The binding is already configured in `wrangler.toml`. Supported formats: JPEG, PNG, GIF, WebP, MP4. Max size: 50MB. Orphaned blobs are automatically cleaned up after 24 hours. 75 76## Testing 77 78```bash 79npm test # Unit tests 80npm run test:e2e # E2E tests (starts local server) 81``` 82 83## Deploy 84 85```bash 86wrangler deploy 87``` 88 89## Initialize 90 91After deployment, run the setup script to register with PLC and initialize: 92 93```bash 94npm run setup -- --pds https://your-pds.workers.dev 95``` 96 97This generates keys, registers your DID with the PLC directory, initializes the PDS, and saves credentials. Handle defaults to the worker hostname.