An in browser local PDS localpds.at
20

Configure Feed

Select the types of activity you want to include in your feed.

JavaScript 49.3%
HTML 22.7%
Go 21.2%
CSS 0.7%
Makefile 0.5%
Other 5.7%
50 1 0

Clone this repository

https://tangled.org/niallbunting.com/localpds https://tangled.org/did:plc:vbkep2ioppqrcefpvn27xhfl
git@tangled.org:niallbunting.com/localpds git@tangled.org:did:plc:vbkep2ioppqrcefpvn27xhfl

For self-hosted knots, clone URLs may differ based on your setup.



README.md

LocalPDS#

Building a PDS on hardware you own.

https://localpds.at

WARNING: This is currently a work in progress. You may loose data or keys.

This project aims to build the infrastructure to allow you to locally host your own PDS (at the moment using a Chrome extension).

Current State#

You can:

  • Login to Bluesky (v0.0.2)
  • Post on Bluesky (v0.0.2)
  • Perform various actions such as liking, replying. (v0.0.2)
  • Your changes are reflected on the network. (v0.0.2)
  • Login using OAuth - (In some places leaflet seems to work) (v0.0.3)
  • OAuth works in more places (v0.0.4).

Example Account#

https://bsky.app/profile/localpds.at

How to use#

  1. Get the chrome extension. (As of 31/MAY/2026 awaiting approval for first version)
  2. Go to the Bluesky login page
  3. Choose localpds.at as the hosting provider.
  4. Type any username and password (your username is from your public key)
  5. Use Bluesky as usual

Architecture#

Your DID is your public key e.g. did:web:vwgjo4bk5hsu7vw7qw9ty8ax6yzyz9w2efd2c9qd0x84b0pn2q1l52.localpds.at. This allows us to server the .well-known/did.json without loading any data.

All data is stored currently in browser localstorage. The client intercepts what it can but various things require some internet accessible URLs. The server does the least it can to allow those functions to work. The server's goal at all points is to act as bridge and not store PDS data.

  • This does mean that you being online is detectable as your PDS will not otherwise be available (this may change with caching).

  • If you're not online it relies on caching done by the app views. It will be interesting to see how long Bluesky etc cache data for.

Client Side#

Intercept requests and serve them locally as if the website is talking to a PDS on the public internet.

Your data gets stored in localstorage in your browser. In the future would be nice to write this to disk using another application (would also mean I wouldn't need to use the chrome debugger permissions).

On update the client makes a request to /ingest which sends a message to the server. This allows the server to push the sync to the relays.

The client also creates a websocket to the /signal to listen for any requests websites may be making in order to serve data.

Server Side#

The server aims to provide all functionalities that the protocol expects to be able to access.

  • Websockets for the /xrpc/com.atproto.sync.subscribeRepos requests. To allow updates to flow to Bluesky.
  • Act as a relay for requests to hit the worker running in the browser.
  • Serve various files such as did.json, atproto-did and OAuth related items.

TODO#

  • Token validation (peer & OAuth)
  • Maybe don't need debugger for all pages. Eg. leaflet.
  • Test out image redirect rather than allowing through so public uploadBlob works.
  • Extension config pages - make them work
    • Copy out private key to move
    • Set URLs plugin is enabled on
    • Edit your data
    • Allow routing through other hosts but localpds.at
  • Support more of the protocol
  • Server to support brief caching of events (probably in memory).
  • Enable P2P file syncing between your machines
  • Write better README's
  • Write a local server that people can run to avoid debugging and is more available
  • Caching - cache so if a user is offline there is some availability
  • Email forwarding
  • Shorter names
  • Hosting
  • Potentially: apps so mobile can use?

Contributing#

If you want to contribute go for it and open a PR.

Use of AI#

As this a POC at the moment I have used AI to get this going. Planning to review the code and strengthen.

Author#

Written by Niall Bunting