When we launched the new atproto.com last month, one of our goals was to make the newly-migrated blog more Atmospheric. At launch, that meant publishing new posts as standard.site Lexicons — making them first-class records in the Atmosphere, not just web pages.

We recently added the next piece: Atmospheric conversations. Each new post now brings a Bluesky thread back to the page, so the conversation happening out in the Atmosphere is visible right where the content lives.

No server required

Internet comments predate even the web, and pulling in chatter for social media is a well-established pattern. Bluesky's own Emily Liu wrote one of the earliest posts about using Bluesky replies as blog comments back in 2024, Cory Zue turned that into a React component shortly after, and there are countless others.

Sequoia, a CLI for publishing static sites via standard.site, also recently shipped their own <sequoia-comments> web component.

This kind of comments thread is one of the easiest ways to get started building Atmospheric websites because many of Bluesky's public APIs, like the one to fetch replies to a post, allow cross-origin requests via a permissive Access-Control-Allow-Origin: * header.

This means a plain HTML page can fetch and render a conversation thread entirely client-side with no server, no proxy, and no third-party hosting required. If you've built websites before, you probably recognize how novel this is, not needing to use a centralized service or manage cumbersome server-side hosting.

In addition to replies, the component we shipped on atproto.com also counts reposts and grabs quote posts to capture the full conversation.

In building this feature, I wanted to embrace the openness of the web as much as possible. <bsky-conversation> is a true zero-dependency Web Component, not built with any JavaScript frameworks or even requiring a build step. One <script> tag, one custom element, and you're done. No build step, no bundler, no React. It drops into any HTML page as-is.

Grab the source from Tangled, check out a demo, and add a Bluesky conversation to any web page right now.

Use the social features you already know

Adding social features to the web goes beyond just adding a bit of JavaScript, though. Social media isn't just a bundle of features, it involves, well, people and people do all kinds of unexpected things. Bluesky has built a composable moderation stack and portable moderation, which extends here as well.

Moderation you already know. Don't want a particular reply showing up on your site? Use Bluesky's "Hide reply from everyone" and it won't appear in the component. Same for quote posts you want to detach. There's even an included CLI tool if you'd rather not open the app.

Identity readers already have. Anyone who wants to join the conversation participates from Bluesky or any other Atmospheric app — no new account, no new login on your site.

Styling that fits your site. The component exposes CSS custom properties and scales with your inherited font size, so it integrates with your existing design rather than imposing one.

Add it to your site

Point <bsky-conversation> at any public Bluesky post and the thread renders inline. The typical pattern is to create a Bluesky post pointing to your article and use that as your conversation anchor.

<script type="module" src="bsky-conversation.js"></script>

<bsky-conversation
  uri="https://bsky.app/profile/did:plc:ewvi7nxzyoun6zhxrhs64oiz/post/3mf2y35apvc2i">
</bsky-conversation>

That's the complete installation. For reliability, use a DID-based URL instead of your handle — if you ever change your handle, the handle-based URL breaks but the DID-based one doesn't.

The header and CTA are customizable as well, and the component supports a small template language for things like reply counts that understand pluralization:

<bsky-conversation
  uri="..."
  header-template="{replies?{replies|reply|replies} in the conversation so far.}"
  engage-text="Join the conversation on Bluesky">
</bsky-conversation>

This started as a very straightforward problem: the blog had moved, the conversation was happening on Bluesky, and there was no connection between the two. The component is now a bridge between the two.

In building this, I was delighted in just how few moving parts were required — no server, no auth, no build pipeline. Just a script tag and the Atmosphere. Grab the source on Tangled and make try it on your own site.