I’ve spent the last few weeks pouring a lot into atmoBB, a phpBB-style forum that runs on atproto, and the features doc has a line at the bottom: “I haven’t built search, notifications, RSS, private messages, or reactions.” Search and RSS I can live without for a while. Notifications are the one that bugs me, because atmoBB isn’t the only app missing them. Nobody on the network has them.

The setup

Someone replies to your thread on an atmoBB forum. You’re over on Bluesky, because that’s where you spend your day. Nothing happens. Someone @mentions you in a Leaflet doc, and nothing happens on Bluesky either. Every app on the network shares one identity and one data repo, and then each one runs its own little inbox that no other app can see into. 😅

The whole pitch of atproto is that you show up to a new app already someone. But a forum only works if people come back, and people come back because something told them to.

Why Bluesky can’t just do it

Bluesky’s notifications don’t live in your repo. They live in the Bluesky appview, and the app pulls them with app.bsky.notification.listNotifications proxied through your PDS. Bryan Newbold laid this out in 2023 in a GitHub discussion about federated notifications: “At the protocol level, app.bsky notifications are in the AppView, and are still authoritatively pulled via a request.” Same thread: “There is an idea floating around to also have a more generic/standard event stream for things like push notifications.” That idea is three years old now!

So the Bluesky appview only knows about app.bsky records. A reply in an atmoBB thread is an app.atmobb.discussion.reply record, and Bluesky’s indexer has no reason to look at it. Which is correct! It isn’t Bluesky’s job. But it means every app rebuilds the same thing. Leaflet has its own in-app notifications, Frontpage has its own, atmoBB would have its own, and none of them talk to each other.

Third-party Bluesky clients have it even worse. Josh Lacal, who builds Catbird, opened Protocol primitives for notifications in March asking for exactly this, and his line was “Push is the lifeblood of modern social apps.” When I looked, the discussion had zero replies and a couple of upvotes.

Who is working on it

Three different shapes so far.

A shared inbox

flo-bit built atmo.pub, a relay that any atproto app can send notifications through. An app asks the user for permission once with pub.atmo.notify.requestPermission, signed with the user’s session, and then sends with its own DID key through pub.atmo.notify.send. The user picks where things land: web push, Telegram, email, Bluesky DM, or a webhook, and everything also goes to one inbox on atmo.pub. The relay is a Cloudflare worker and the whole thing is open source with a self-hosting guide. Apps are curated for now. It’s the most complete thing that exists, and it has 13 stars (including me!) on GitHub as I write this.

Watch the firehose

fig runs microcosm, and one of the pieces is Spacedust, which pulls every link out of the firehose and re-emits them, filterable by target. Their pitch is “notification services for any lexicon.” Every social interaction on atproto is a link (a reply points at a post, a mention points at a DID), so a service that watches for links to you across every collection is a cross-app notification feed that no app has to opt into. It covers public data, which is the same thing the firehose covers.

I did make a fun little example of using atproto for this

Put them in a space

The permissioned data work, now called spaces, is the third shape. Daniel Holmgren’s post on modeling communities has an aside where a community app wants to “deliver notifications across all modalities,” and the sketch is that the event gets published in the event space and an “event notification” gets published into the Bluesky space. It’s the atmo.pub idea, except the inbox is a space you own and any reader you authorize can render it. Nobody has built it. Meri’s roomy roadmap has push notifications as item four, after private spaces and roles, which is about where I’d put it too.

(There are also “write notifications” in the permissioned data proposal, but those are a sync signal between servers, not a thing a person reads. Confusing name!)

What this means for atmoBB

Public boards are the easy half. A reply is a record that points at its thread, and an @mention resolves to a DID at write time and goes into the record as a facet. Something watching Spacedust for links to your DID would catch both, and it wouldn’t care whether the reply came from atmoBB or from a totally different forum app on the same lexicon. That’s the part that makes me want to build a tiny standalone site again. 😭

Members-only boards are the hard half. They live in a Happyview permissioned space, which means Postgres, which means nothing watching the firehose will ever see a reply there. The forum itself is the only thing that knows the reply happened, so for those it has to be atmo.pub or a space-based inbox or something that can pushed into.

I’m… going to wait and see. I might write might own little notifications that are off-protocol for now hoping 🤞 that someone else solves it.

So

I made a fun little project and that’s about all I got out of this except that I’m going to wait 🤷‍♂️