{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreigm32ufydlgyaefwo7zvauqsjlrpfgpjpdtpbvhfzb7uscif26x64",
"uri": "at://did:plc:xs2vgih3wx5mnyiuqvbzar5h/app.bsky.feed.post/3moixqughsvs2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreiaiooodbfbplhu3vy7264tjswg77zu7wyvixq7b3xwijfs3fprgvy"
},
"mimeType": "image/png",
"size": 13018
},
"description": "Comments are about as old and basic as the social web gets, so I assumed ATProto would have them figured out. It doesn't, not yet. Here is my take on why standard.site deferred comments on purpose, the handful of work-arounds people built, and what it says about how young the protocol still is.",
"path": "/comments-on-atproto/",
"publishedAt": "2026-06-17T18:41:59.000Z",
"site": "https://herve.bzh",
"tags": [
"ATProto",
"comments",
"SkyPress",
"standard.site",
"here",
"Off Protocol podcast",
"@jimray.bsky.team",
"@awarm.space",
"bsky-conversation",
"margin.at",
"own docs"
],
"textContent": "I published my first post on this blog almost 20 years ago. I wasn’t always very active on this blog, but one of the things that kept me going was the interactions I got to have with readers. In fact, in the first few years I was part of a small group of people who often commented on each other’s posts one of us would publish. The comments were my community.\n\nI mention this because comments are about as old and as basic as the social web gets. So when I started poking at the AT Protocol, building SkyPress and reading up on standard.site, I assumed comments would be a solved problem. A protocol built for social, in 2025, surely has commenting figured out. It turns out it doesn’t, and as I’m digging into the standard some more, I’m really curious about its status and its next steps.\n\n## standard.site left them out on purpose\n\nThe standard.site lexicon is documented here. Here is what’s currently supported:\n\n * Publications: a collection of documents. Let’s call that a blog 🙂\n * Documents: a single document, part of a publication. Let’s call that a blog post.\n * Subscriptions: used to track users following a publication.\n * Recommends: used to, well, recommend documents. I think of it as likes for documents.\n\n\n\nComments are not of there. I went looking for discussions around why those were missing, and got some answers on the Off Protocol podcast, hosted by Jim Ray (@jimray.bsky.team). Their rule of thumb, as Jared (@awarm.space) from Leaflet put it, is that “the amount of existing implementations we want should be proportional to the complexity of the new lexicon.” Comments are complicated, and nobody is happy with what exists yet:\n\n> For something like comments, that’s actually pretty complicated and has a lot of implications for content and various moderation things and all these kinds of stuff. Leaflet has a comment lexicon, but we’re not like super happy with it or anything like that.\n>\n> @awarm.space\n\nSo they’ve held off on purpose. As Jared summed it up, “so far we have chosen the easy parts of the problem”, “that sort of maximally useful and least gnarly set of the problems.” I think that restraint is the responsible call. But it does mean that today, if you want comments on your long-form post, you’re on your own.\n\n## So everyone built their own\n\nIf you’re building your own blog on ATProto today, there isn’t a single work-around. You have a few options:\n\n * **A companion Bluesky post.** You publish your article, then also post a normal Bluesky post pointing at it, and treat its replies as your comments. Jim Ray’s `bsky-conversation` web component does this nicely. The catch is that those replies are regular Bluesky posts. They’re capped at 300 characters, you can only use plain text. I know I ramble, but I think that’s annoying whenever you want to post a reply to a well-thought blog post or essay.\n * **A native comment record.** Leaflet built its own `pub.leaflet.comment`, with no character limit, rich text, threading, even comments anchored to a specific passage like margin notes in a doc. It’s really nice. But it lives in Leaflet’s namespace, so only Leaflet readers see those comments. They’re invisible to Pckt, to my own reader (so far), to anything that isn’t watching for that exact record type.\n * **A whole separate annotation layer.** Then there’s margin.at, which lets you annotate, highlight, and reply to _any_ URL on the web, using its own `at.margin.*` records built on top of the W3C Web Annotation model. It’s a clever, broader idea, but it’s another shape that doesn’t line up with any of the above.\n\n\n\nFor where I stand, it seems that the hard part isn’t the implementation, or the lexicon, it’s agreeing on the protocol underneath. On that same podcast episode, Jim Ray walked through the problems:\n\n> the comment would in theory be stored on my PDS… How do I actually gather up all of the different comments that have been left through some kind of backlinks mechanism? But then, you know, what happens if that PDS disappears? […] How do you show a tombstone comment? […] How do you handle things like moderation? Who does the moderating?\n>\n> @jimray.bsky.team\n\nEvery one of those is real. Your data lives on your PDS, so when you comment on my blog post, that comment record lives on your PDS, not mine. My PDS has no idea it exists, and there’s no query anywhere that says “give me every record on the whole network that references this post.” That question simply can’t be asked directly.\n\nSo how does a reader show comments at all? It listens to the firehose, the stream of every record being written across the network, catches comment records as they fly past, and indexes them itself. That works, but it means a comment is only ever visible on a reader that happens to be watching for that specific record type. A `pub.leaflet.comment` shows up in Leaflet because Leaflet is listening for it. Nobody else is.\n\nAnd then there’s the deleted-commenter problem Jim flagged. If someone deletes their account, their comment can leave a ghost behind: an indexed copy sitting in some reader’s database with no live PDS backing it.\n\nI think we’ve solved some of those problems in other areas of the web, but the decentralization of the data certainly makes things a bit more complicated.\n\nSo for now we have work-arounds. You can start using the companion-post trick in your implementation already, it’s most likely the easiest to pull off, especially since we’re already creating companion-posts alongside standard.site records to promote the posts on Bluesky. Leaflet’s comment record is lovely. Margin is an interesting idea, brings a bit of a twist on the “threaded comments” idea. And the protocol-level problems really are hard. But I find it interesting that a network built for social interaction hasn’t landed a shared answer to commenting, the thing that made the social web social in the first place.\n\nTo be fair, there’s something I like in that mess. Different teams each built a comment system because nothing stopped them: the protocol is new and flexible, people sign in with their existing ATProto account, and the data is already on their PDS, so the barrier to trying your own approach is close to zero.\n\nstandard.site is built to be extended; its own docs say the existing properties “should not be seen as constraints, but rather as starting points.” So going off and building your own thing is the intended move, not a hack. That’s the same energy that makes the whole atmosphere feel vibrant and fast right now. Everyone is shipping new things every day, is finding new creative things to store on PDS. The downside is solutions that don’t talk to each other.\n\nMaybe that will change with time. As the dust settles, the most popular solutions to different problems will be the ones the protocol will adopt?\n\nMaybe a `site.standard.comment` will eventually show up? I hope so. For now, this problem is, to me, one of the clearest examples of how young this all still is.\n\nIt does make it interesting to dive in some more!",
"title": "Comments are a basic web feature. So why aren’t they solved on ATProto yet?"
}