A personal log for tracking where you left off in books, shows, films, games, and podcasts. I built it for myself. Your records live on your own ATProto PDS. There is no Breadcrumbs database.
Goodreads has your reading history. Letterboxd has your watches. Steam has your hours. None of it lives in the same place, and all of it belongs to someone else’s server. Breadcrumbs stores everything as typed records on your PDS. No tracking. No advertising. No data resale. When you sign in, that’s the only copy.
The platform problem.
I built this to understand ATProto by actually using it. The use case was close at hand: a personal log that doesn’t strand your data. Put a book down for four months and you lose the thread. Come back to a series and you’re lost in an episode. Most people just don’t come back. The tracking problem is table stakes. The interesting part is that every existing tracker owns what you log.
Breadcrumbs doesn’t. There is no Breadcrumbs database. Entries write to a Personal Data Server you already own. If the app disappears, your records don’t go with it. If someone builds a better client against the same lexicon, you can switch without migrating anything.
It was built for one person. It’s shared because keeping things private until they’re perfect is a trap worth avoiding.
Built on ATProto.
ATProto is the open protocol behind Bluesky. The core idea: your data ties to your identity, not to the application. Four properties that follow from that.
Your PDS. Your records.
Entries write to a Personal Data Server that belongs to you. Nothing is stored on Breadcrumbs’ servers. Sign in with your Bluesky handle; your data is in your account.
atproto.com · Personal Data Server specPortable by design.
The lexicon is public. Any developer can read app.breadcrumbs.entry records from any PDS without asking. If someone builds a better UI against the same schema, you can switch without migrating anything.
DID-based identity.
Your Bluesky handle resolves to a DID (a decentralized identifier) that persists independent of any service. Your identity stays intact even if your PDS provider changes.
W3C DID spec · atproto identityLeast privilege auth.
Breadcrumbs uses ATProto app passwords with DM scope off. It only requests read/write access to your records. Nothing else.
ATProto app password specStack and schema.
HTML + JS + CSS, no build step, deployed to Cloudflare Pages. Media metadata pulls from external APIs via Pages Functions. Everything writes to your PDS. Click a collection to see its schema.
Example:
{ "title": "Project Hail Mary", "authors": ["Andy Weir"], "status": "app.breadcrumbs.defs#inProgress", "progress": { "currentPage": 284, "totalPages": 476 }, "rating": 5 }#notStarted · #inProgress · #completed · #abandoned · #onHoldapp.js and breadcrumbs.css, no build step
Open source. Fork it.
No install, no account required to try it. Demo Mode runs on local storage only if you want to explore the UI before signing in. Source is on GitHub under MIT. The lexicons are public. If you want to build a different client against the collections, you don’t need to ask.
Try the demo.
Demo Mode uses local storage. No sign-in, no PDS writes, no account needed.
Sign in with your Bluesky handle.
Create an app password at bsky.app/settings/app-passwords. DM scope off. Paste it in. Your PDS is now connected.
Start logging.
Add a book, show, film, game, or podcast. Search fills in cover art and metadata automatically. Your entry writes to your PDS.
One thing worth knowing: ATProto records are public by design. Anyone who knows your handle can read your Breadcrumbs entries through tools like atproto-browser.dev or any other ATProto client. If you want a private reading log, this isn’t the right tool. The in-app Privacy screen has the full version of this.
Built for one person. No database, no tracking, no ads. Sharing it in case it’s useful to someone else.