Personal web site

Fediverse profile via Bridgy Fed

Bridgy Fed is a decentralized social network bridge. It connects the fediverse, the web, and Bluesky. If you're on one of these networks, you can use Bridgy Fed to follow people on other networks, see their posts, and reply and like and repost them. Likewise, they'll be able to see you and your posts too.

Click here to get started, or read on for more information and setup details.


/.well-known/host-meta
/.well-known/webfinger

Here are instructions for a few common web servers:


From Bluesky

  • How do I get started?
  • To bridge your Bluesky account into the fediverse and interact with people there, follow @ap.brid.gy on Bluesky.

    After a few minutes, your Bluesky account will appear in the fediverse as @[handle]@bsky.brid.gy. For example, @snarfed.bsky.social on Bluesky is bridged into the fediverse as @[email protected].

    Alternatively, you can find and follow bridged fediverse accounts without bridging your own account, but they won't see your posts or interactions.

  • How do I find a bridged fediverse account?
  • Search in Bluesky for their fediverse address (eg @[email protected]) or profile URL (eg https://indieweb.social/@snarfed), and then click the People tab. If they've enabled the bridge, they'll show up there.

    Bridged fediverse accounts will appear in Bluesky as @[user].[instance].ap.brid.gy. For example, @[email protected] is bridged into Bluesky as @snarfed.indieweb.social.ap.brid.gy.

  • How do I find a bridged web site?
  • To follow a web site, first enter it here to make sure it's set up, then wait a minute, then search for it in Bluesky as [domain].web.brid.gy. For example, nature.com is bridged into Bluesky as nature.com.web.brid.gy.

  • Can I use Bluesky's reply controls?
  • Yes! Bluesky's reply controls apply to accounts bridged from the web and the fediverse as well as to native Bluesky accounts. Those platforms don't have reply controls, so if you bridge your Bluesky account and post with reply controls, people on the fediverse and the web will still be able to reply, but those replies won't show up in Bluesky.


  • To Bluesky

  • Which stuff of mine can get bridged into Bluesky?
  • Profiles, follows, posts, images, videos, hashtags, @-mentions, and content warnings. Also replies, likes, and reposts if the original post was already bridged.

  • Which stuff can't get bridged into Bluesky?
  • Polls, edits/updates, or (most) GIFs.

  • What happens when I report a bridged Bluesky user?
  • Bridgy Fed sends your report to the Bluesky team's official moderation service, which handles it, and takes action if necessary, just like with native Bluesky accounts.

    Also see Bridgy Fed's moderation policy and functionality.

  • I edited a post, but it didn't get edited in Bluesky!
  • Bluesky doesn't support editing posts right now. Bridgy Fed currently sends edits via the underlying AT Protocol, which does currently support them, but the Bluesky app itself doesn't. Hopefully eventually!

  • Why can't I see a video?
  • Bluesky currently limits videos to 60 seconds, 50MB, and .mp4, .mpeg, .webm, or .mov. If you're seeing a "Video not found. Retry" error, the original video may not satisfy those requirements.

  • Can I use my own domain as my Bluesky handle?
  • Yes! First, you'll need your bridged account's DID. You can get it by DMing did to the Bluesky Bridgy Fed bot account (eg @[email protected]), or go to your user page and click the next to to your bridged Bluesky account link.

    Then you'll need to connect your domain to your bridged Bluesky account. You can do this with DNS by following step 5 in the How do I set this custom domain as my handle? section here. Or, you can do it with HTTPS by following the HTTPS well-known Method section here. Once you're done, you can check your work here.

    Finally, if your account is on the fediverse, DM username [domain] to @[email protected]. For example, to set your handle to my.site.com, DM the exact text username my.site.com. If you're bridging a website, click the button on your user page.

  • How can I see the full text or original URL for a bridged post?
  • If a post bridged into Bluesky is truncated, it will include an embed with a link to the original post. You can also find the original post link indirectly by opening the author's profile and following the link in their bio to their original account.

    For developers, Bridgy Fed includes the full text and URL for bridged posts and profiles inside their AT Protocol records. Bridged app.bsky.actor.profile records have bridgyOriginalDescription and bridgyOriginalUrl fields, and bridged app.bsky.feed.post records have bridgyOriginalText and bridgyOriginalUrl fields. Here's an example:

    {
      "$type": "app.bsky.feed.post",
      "text": "This is a very long post that got cut off and ...",
      "bridgyOriginalText": "<p>This is a very long post that got cut off and has more to say.</p>",
      "bridgyOriginalUrl": "https://indieweb.social/@snarfed/abc123",
      "..."
    }
    

  • From the web

  • How do I get started?
  • Your web site will need webmention support or an Atom or RSS feed discoverable from your home page, so that Bridgy Fed can find your posts. When you're ready, connect your site, then try following your site from the fediverse. If that looks good, start following other fediverse users!

    We recommend that your site supports webmentions. You can see a notifications feed of your interactions from other networks - replies, reposts, likes, etc - but to get them back to your site, it needs to support webmentions. Check out the IndieWeb wiki for instructions for your web server.

    If your site serves WebFinger requests itself, Bridgy Fed won't support it. This generally happens when your site is already a fediverse instance or has its own fediverse integration. If Bridgy Fed tried to work in these cases, it might conflict with your existing ActivityPub server.

  • Where does my profile info come from?
  • Your site's bridged profile can come from a few different things on your home page. Here's what Bridgy Fed looks for, in order of preference:

    Here's a minimal example of h-card HTML that sets your name and a profile picture:

    <span class="h-card">
      <a class="u-url" rel="me" href="/">Alice Foo</a>
      <img class="u-photo" src="/me.jpg" />
    </span>
    

    You can use indiewebify.me to check your site's h-card interactively, but note that that doesn't check that it's representative. In the common case, this just means that your h-card needs a link to your home page with the u-url class. See the representative h-card spec for more details.

    If you want to set a header image, add a u-featured image to your h-card, eg:

    <img class="u-featured" src="/my-header.png" />
    

    Your Bluesky handle will be yourdomain.com.web.brid.gy.

    By default, your fediverse address will be @[email protected]. Many services (eg Mastodon) default to only showing the username, so this generally shows up as just @yourdomain.com in posts, and the full address appears on hover.

    We recommend this for simplicity and predictability, for everyone else as well as you, but if you want a different username, you can set it by adding an acct: u-url link inside your h-card with [email protected], eg:

    <a class="u-url" href="acct:[email protected]"></a>
    
  • How does Bridgy Fed find my posts?
  • Bridgy Fed can discover web site posts via webmentions and Atom/RSS feeds.

    The first time someone follows a web site via Bridgy Fed, it looks for an Atom or RSS feed. If it finds one, it extracts and bridges those posts, then periodically checks for new posts.

    Instead of waiting for that periodic poll, you can bridge a new or updated post immediately by including microformats in your HTML and sending Bridgy Fed a webmention. Include a link to https://fed.brid.gy/ in your post, and if your web server supports webmentions, it should send one automatically. Alternatively you can send one manually. (Note that triggering via webmention requires your post HTML to be marked up with microformats.)

    Once you send Bridgy Fed a webmention from your site - any webmention! - it will stop reading posts from your Atom or RSS feed, and expect webmentions instead for all posts in the future. You can use this to prevent automatically bridging all posts, and instead choose proactively which of your posts to bridge.

    Here's example HTML for a post:

    <div class="h-entry">
      <p class="e-content">Two naked tags walk into a bar. The bartender exclaims, "Hey, you can't come in here without microformats, this is a classy joint!"</p>
      <a class="u-bridgy-fed" href="https://fed.brid.gy/" hidden="from-humans"></a>
    </div>
    

    The link to fed.brid.gy may be blank. If so, it should include the hidden attribute to be kind to screen readers and keyboard navigation users. The u-bridgy-fed class is optional but useful in some cases to prevent microformats2 parsers from interpreting the link as an implied u-url.

  • How does it interpret and translate my posts?
  • If your post has microformats, which many web servers include automatically, Bridgy Fed uses them to determine whether it's a note, article, like, repost, reply, or follow. Here's an example of a note:

    <div class="h-entry">
      <p class="e-content">Two naked tags walk into a bar. The bartender exclaims, "Hey, you can't come in here without microformats, this is a classy joint!"</p>
    </div>
    
  • How does it decide which parts of my posts to include?
  • If a post has microformats, Bridgy Fed looks first for the e-content class, then the legacy entry-content class. It also understands and translates microformats2 classes like u-photo, u-video, p-category, and more.

    Otherwise, Bridgy Fed uses Twitter card, Open Graph, and related meta tags in your HTML.

    Bridgy Fed includes the full contents of all posts, specifically everything inside e-content. However, not all bridged networks currently show the full contents of all posts.

    For example, text-based posts fall into two broad buckets: short notes for microblogging and longer articles for long-form articles and blog posts. In the IndieWeb, we differentiate based on whether the post has a title: articles generally have titles, notes don't.

    In the fediverse, Mastodon currently shows the full text of notes, but for articles, it only shows their titles and a link to the full article. This is because it and most other fediverse apps are designed primarily for smaller notes, not longer articles.

    Also, Mastodon preserves HTML links and line breaks and some formatting, but not all. Other fediverse servers vary in their HTML handling.

  • These can happen for a couple reasons. For articles, this is expected behavior, as described above. The link is a Bridgy Fed URL that redirects to the original post on your web site. This is because Mastodon requires ActivityPub (ie fediverse) object URLs to use the same domain that serves them, which in this case is fed.brid.gy. We know it's awkward; sorry for the ugliness!

    Otherwise, this may be the invisible fed.brid.gy link that's required to trigger Bridgy Fed. Mastodon will show a preview of links even if their text is blank, so if your link is inside your e-content microformats2 element, that's probably what's happening. You can prevent that by moving it outside of e-content. It can go anywhere in your HTML!

  • How do I reply to a fediverse or Bluesky post?
  • Put the reply in a new post on your web site, and include a link to the post you're replying to with class u-in-reply-to, as if you were publishing a normal IndieWeb reply. For example:

    <div class="h-entry">
      <p class="e-content">Highly entertaining. Please subscribe me to your newsletter.</p>
      <a class="u-in-reply-to" href="https://indieweb.social/@tchambers/109243684867780200"></a>
      <a class="u-bridgy-fed" href="https://fed.brid.gy/" hidden="from-humans"></a>
    </div>
    
  • How do I like or repost a fediverse or Bluesky post?
  • Liking and reposting are almost exactly the same as replying. The only difference is that you use u-like-of for a like or u-repost-of for a repost.

    <a class="u-like-of" href="https://indieweb.social/@tchambers/109374703563569354"></a>
    
    <a class="u-repost-of" href="https://cosocial.ca/@evan/110290575042195305"></a>
    
  • How do I follow someone?
  • If your web site supports IndieAuth, go to your user page, click the Following link, then enter the address of the account you want to follow.

    You can also follow someone by posting an IndieWeb follow on your site, including the u-follow-of microformats2 class, and sending a webmention to Bridgy Fed. Your site may do that automatically if it supports webmentions. For example:

    <div class="h-entry">
      I'm now following <a class="u-follow-of" href="https://mastodon.social/@adactio">@[email protected]</a>!
      <a class="u-bridgy-fed" href="https://fed.brid.gy/" hidden="from-humans"></a>
    </div>
    
    This method doesn't require IndieAuth, and it can be automated.
  • How do I unfollow someone?
  • Go to your user page, click the Following link, find the account you want to unfollow, and click the X next to their address. Like following, this requires your web site to support IndieAuth.

  • How do I include an image in a post?
  • Use <img class="u-photo"> for the image in your post. For example:

    <img class="u-photo" src="/full_glass.jpg" />
    I love scotch. Scotchy scotchy scotch.
    
  • How do I include a video in a post?
  • Use <img class="u-video"> for the video in your post. For example:

    <video class="u-video" src="/dancing.mp4"></video>
    Dancing dancing dancing
    
  • How do I use hashtags?
  • Use p-category and link the hashtag to a fully qualified URL. (Any URL you want!) Fediverse sites like Mastodon will generally rewrite the link to point to a search for that hashtag on the local instance. For example:

    <div class="h-entry">
      <p class="e-content">
        chasing the fun laser
        <a href="https://indieweb.social/tags/caturday" class="p-category">#caturday</a>
      </p>
    </div>
    

    The leading # character on the hashtag text is optional. If you don't include the hashtag in e-content, or include it but not inside an <a> link, fediverse sites won't add the hashtag text or link themselves, but your post will still be indexed in searches for that hashtag.

  • How do I @-mention someone?
  • Include a link to their profile in your post's content with an @ character at the beginning of the link text. For example:

    Hi <a href="https://mastodon.social/@adactio">@adactio</a>!
    

    The link and text are both necessary!

  • How do I edit an existing post?
  • Edit the post on your web site, then send another webmention to Bridgy Fed for it. Bridgy Fed will refetch the post and updated it everywhere it was originally bridged.

  • How do I delete a post?
  • First, delete the post on your web site, so that HTTP requests for it return 410 Gone or 404 Not Found. Then, send another webmention to Bridgy Fed for it. Bridgy Fed will refetch the post, see that it's gone, and send an Delete activity for it to the fediverse.

  • Can I publish only one part of a page?
  • If that HTML element has its own id, then sure! Put the id in the fragment of the URL that you publish. For example, to publish the bar post here:

    <div id="a" class="h-entry">foo</div>
    <div id="b" class="h-entry">bar</div>
    <div id="c" class="h-entry">baz</div>
    

    ...add the id to your page's URL in a fragment, e.g. http://site/post#b here.

  • How do replies, likes, and other interactions show up on my site?
  • To receive likes, reposts, replies, @-mentions, and follows from other networks, make sure your site accepts webmentions! Bridgy Fed translates those interactions and sends them to your site as webmentions. The source URL will usually be a proxy page on a subdomain of brid.gy. For best results, make sure your webmention handler detects and handles u-url links.

  • How do I read my timeline/feed?
  • Your user page has links to your timeline/feed, ie posts from people you follow, in HTML, Atom, and RSS formats. Add them to your feed reader or read them in your browser!

    (Secret pro tip! Add &quiet=true to the end of any Bridgy Fed feed URL to omit likes, reposts, and follows, and only show original posts and mentions.)

  • Are there notifications?
  • Yes! Your user page has a feed of your notifications - mentions, replies, likes, reposts, follows, etc - in HTML, RSS, and Atom formats, which you can subscribe to in any reader. (And &quiet=true - see above - works with these feeds too.)

  • How can people find and follow me?
  • They can search for your web site! Often you can enter your domain, eg yourdomain.com, in any fediverse or Bluesky search box. If that doesn't work, try your full address, either @[email protected] or @[email protected] in the fediverse and yourdomain.com.web.brid.gy in Bluesky.

    Your user page has a Followers link that shows you all of your followers. It has a "remote follow" form where people can enter their fediverse address and follow you directly.

  • How can I see what my posts look like on other networks?
  • On Bluesky, just check out your bridged profile!

    In the fediverse, it varies by server. For Mastodon, open your list of followers in Bridgy Fed and click on one to open their profile. Then, inside that Mastodon instance, search for your site's address, click on it in the search results, and you'll see your fediverse profile and all of your posts that were delivered to that instance. This may not be all of them, depending on how long and when people on that instance have been following you.

    This general process should often work in other fediverse servers too.

    Note: in Mastodon, each of your posts on a given instance will have a permalink inside that instance, eg mastodon.social/@[email protected]/109729052169033033, but those permalinks only go to Mastodon if you're logged into that instance. If you're not, they redirect to the original post on your site.

  • Can I make my posts show up when people search for their URLs in the fediverse?
  • Yes! Add this line of HTML to each post that you publish with Bridgy Fed and want to be searchable, replacing [URL] with that post's URL:

    <link rel="alternate" type="application/activity+json" href="https://fed.brid.gy/r/[URL]">
    

    Search is limited in Mastodon and much of the overall fediverse, so this won't index the full text of your posts, but it will make them show up in search results when you search for your post's full URL, which people commonly do in the fediverse to find and interact with posts.

  • Can I use my own domain as my handle on other networks?
  • For the fediverse, yes! By default, your web site's bridged handle on other networks includes web.brid.gy, eg @[email protected] on the fediverse, but you can use your own domain instead. Here are instructions for fediverse handles.

    For Bluesky, not yet, but hopefully eventually. Follow this GitHub issue.

  • I disabled my bridged profile, or deleted a post, but it's still visible in the fediverse!
  • Sadly, this is a somewhat inherent part of the fediverse itself. When you disable the bridge for your account, Bridgy Fed sends Deletes to every fediverse instance where you had a follower, but it doesn't currently know about other instances that may have loaded and cached your profile. Same with posts bridged into the fediverse that you later delete. Those cached profiles and posts will eventually disappear over time.

  • Could other networks' instances get their own brid.gy subdomains, so that admins can federate with or block them individually?
  • This is a great idea! It's difficult to implement technically - I'd need to build and run my own DNS server with custom behavior for resolving multi-level wildcard records - but it's definitely doable.

    However, servers and domains on other networks are very different from fediverse instances:

    • Bluesky PDSes are similar to shared web hosts; they're more generic and interchangeable than fediverse instances. They don't define affinity groups, user-visible communities, or moderation boundaries. It's not clear that they're useful for domain level federation decisions like fediverse instances are.
    • IndieWeb sites generally represent a single person. They're often domains, but when they're subdomains, eg on wordpress.com or blogspot.com, those are often shared hosting platforms that don't define clear communities or moderation boundaries either.

    Another difficulty is that accounts on Bluesky have long-lived, server-independent ids. If we used a Bluesky user's PDS domain in their fediverse handle, that handle would change every time they migrated to a new PDS, and they'd lose all of their followers and followings, even though their Bluesky account ID itself hadn't changed.


  • Background

  • Who are you? Why did you make this?
  • I'm Ryan Barrett. I'm just a guy who likes the web and owning my data. I build and run Bridgy Fed myself, with occasional contributors and lots of broader support.

    I love how decentralized social networks like the fediverse and the IndieWeb let us move away from walled gardens controlled by single monolithic entities. I love that we can control our own destinies online, nurture and grow our own communities and instances, and still interact with people elsewhere. I want to be able to interact across networks just like we interact across servers. That's why I build bridges like Bridgy Fed.

  • How much does it cost?
  • Nothing! Bridgy Fed is small, and it doesn't cost much to run. I don't need or want donations, paying customers, ads, venture capital, or any other form of money. Hosting costs are manageable right now, and it would have to grow 10-100x for that to change meaningfully. If that happens, I'll celebrate, and I'll still continue running it as is. I have experience scaling services like these as personal projects. I'm in the fortunate position to be able to do that; it's one way I try to give back to the open web and the decentralized social ecosystem.

    If you really want to contribute, file an issue or send a pull request, or donate to your network or instance of choice!

  • What do you do with my data?
  • Nothing! Bridgy Fed isn't a business, and never will be, so we don't have the same motivations to abuse your data that other services might. More concretely, we don't sell or otherwise expose any of your data to third parties, even in aggregate. We only handle data that you've chosen to make fully public. We never have access to any of your passwords, credentials, accounts, or other non-public information.

  • How long has this been around?
  • I started thinking about bridging different social networks when I discovered them in the early 2000s. I started talking about bridging decentralized social networks specifically in 2016, led a session on it at IndieWeb Summit in July 2017, wrote up concrete designs soon after, started working on Bridgy Fed in August 2017, and launched it on October 22, 2017.

  • What are the terms of service?
  • Bridgy Fed's terms of service are simple. You agree not to deliberately attack, breach, or otherwise harm the service. If you manage to access private keys or other sensitive data, you agree to report the vulnerability and not use or disclose that data.

    Otherwise, you may use the service for any purpose you see fit. However, we may terminate or block your access for any reason, or no reason at all. (We've never done this, and we expect we never will. Just playing it safe.)

    Do you an administer an instance or other service that Bridgy Fed interacts with? If you have any concerns or questions, feel free to file an issue!

  • What is your content moderation policy?
  • Content moderation for decentralized social networks, and for bridges, is complicated. Bridgy Fed itself doesn't have an exhaustive content moderation policy. Instead, I try to keep these principles in mind:

    • My primary goal is to empower each network's existing moderation ecosystem. Most decentralized social networks have existing, often mature mechanisms for content moderation. The fediverse has blocks and defederation and IFTAS, the IndieWeb has Vouch and Akismet, Bluesky has labeling, even Nostr has mutes and shared mutelists and moderated groups.

      I try to ensure that those mechanisms all work with bridged accounts just as well as with native accounts, up to and including defederation. I'm always ready to hear admins' concerns and try to help! But if an instance determines that they need to block a Bridgy Fed network (domain) entirely, that's their prerogative, and I'll support them.

    • Bridgy Fed is more network infrastructure than content platform. Bridgy Fed is not a social network, nor is it an instance in one. It's a relay: it copies and translates content and interactions between existing networks and platforms. It stores some content for a moderate period of time, in order to do its job, but not forever, and it doesn't host images or media at all.

    • I build run Bridgy Fed largely alone, as a side project. It's open source, and other people contribute occasionally, which is great! But so far, there isn't a robust community building it. It's just me, sometimes full time, usually alongside a day job. I can't hire a dedicated trust and safety team, I don't expect to recruit volunteer moderators, and I'm unlikely to become an expert myself. I'm just doing my best as an amateur, with the support of organizations like IFTAS.

    • Having said all that, I don't plan to run a Nazi bar. I have no interest in enabling harmful behavior like harassment or incitements to violence, whether knowingly or unknowingly. I reserve the right to remove content and accounts from Bridgy Fed for any reason, or no reason at all.

    These are principles, not a policy. When a user or post gets reported to me, I don't follow this letter by letter to determine what to do. The language here will evolve over time. However, I hope to live up to this in spirit for the long run.

    Please reach out and let me know your thoughts! And feel free to report anything you see on Bridgy Fed that you think shouldn't be there. You can file an issue on GitHub or ping me on your social network of choice.

  • I found a bug! I have a feature request!
  • Great! Please file it in GitHub. Thank you!

  • I found a security vulnerability!
  • Oof. Thank you for reporting it! Please file an advisory on GitHub. We may provide monetary awards for reports of significant vulnerabilities, eg reading or modifying users' private keys, if you follow these rules:

    • Vulnerabilities must be in the application itself, not unrelated services like email (eg SPF/DKIM/DMARC).
    • Out of scope: rate limiting, XSS/CSRF attacks (Bridgy Fed has no authenticated sessions or private data accessible to users).
    • Public user data is intentionally public. That's not a vulnerability.
    • No automated fuzzing, DoSes, or other high volume traffic. We block this traffic, and it will disqualify you from any possible award.

    Otherwise, the code is open source, feel free to try to break in, let us know if you succeed!

  • What's your succession plan if you can't run Bridgy Fed any more?
  • The succession plan for Bridgy Fed is largely the same as for any other non-commercial open source project. Ideally, I find someone willing to take it over, transfer the hosting and development accounts to them, and it continues running as is. Worst case, the code is open source and licensed as public domain, so anyone can set up their own instance and continue development. If that happens, bridged accounts based on on *.brid.gy subdomains and existing private keys would be orphaned, but the new instance could continue to bridge them with its new domain(s) and keys.


  • Development

  • What are Bridgy Fed's product and engineering values?
  • What's important to Bridgy Fed and its development? How do we make technical and design decisions and prioritize work? One way to do this is to explicitly enumerate its product and engineering values, along with their priorities. Bryan Cantrill describes this well.

    As far as I can tell, Bridgy Fed's top product and engineering values are:

    • Quality: expected functionality works consistently, with minimal bugs, surprises, or outages.
    • Functionality: common features and use cases are supported as broadly and comprehensively as possible.

    Bridgy Fed's second tier of product and engineering values are:

    • Safety and security: Bridgy Fed minimizes harm to its users. The primary way this currently manifests is that it only bridges fully public data, and it enables and supports the networks' own moderation features (blocking, reporting, etc). It also uses modern secure coding and ops practices to minimize vulnerabilities that could expose private keys or other sensitive information.
    • Accessibility: users should mostly fall into a "pit of success" with minimal work on their end. Discovering and following users on other networks should be as easy as possible. After that, all interactions should work automatically, transparently.
    • Transparency: it should be easy for users to understand what Bridgy Fed is doing. This includes per-user dashboard pages in the web UI, verbose public logs, and comprehensive documentation.
    • Scalability: we want to handle as much usage as we receive, as automatically as possible. This doesn't mean that Bridgy Fed is designed to handle millions of users today, just that it could be, and that we'd prioritize it.
  • Other possible values include maintainability, operability, feature velocity, innovation, debuggability, performance, efficiency, standards compliance, user growth, and more. Those can all be good, and we may aim at some of them too, but less than the explicitly chosen values above.

  • How do the different protocols compare?
  • Here's a table showing how they stack up on a number of factors. It's obviously oversimplified, but hopefully still right in spirit, focusing on how they're deployed and used in the real world. For example, identity in ActivityPub is technically URL-based, but in practice the fediverse uses WebFinger user@domain identifiers more or less universally, so the table reflects that.

    Feedback is welcome!

    IndieWeb ActivityPub + WebFinger AT Protocol Nostr Farcaster
    governance non-profit, W3C W3C, FEPs C-corp now, IETF eventually? BDFL, NIPs, adoption based FIPs, adoption based
    user identity DNS username + DNS did:plc + did:web,
    DNS handles
    public key, DNS handles public key, blockchain, ENS usernames
    object ids URL URL at:// URI,
    data hash
    data hash user id + data hash
    data format microformats2 ActivityStreams 2 app.bsky lexicons Nostr events Custom schema
    serialization HTML JSON JSON (Lexicon), DAG-CBOR, CAR JSON Protocol Buffers
    delivery push/pull posts,
    push responses
    push pull pull gossip + pull
    transport HTTP HTTP HTTP + WebSocket (XRPC) WebSocket gRPC + libp2p
    topology peer to peer federated servers, two tier federated servers,
    decoupled services, multi-tier
    interchangeable relays,
    two tier
    interchangeable hubs,
    two tier
    security model SSL, one user per domain transport signatures,
    custodial keys
    data signatures,
    custodial + user-owned keys
    data signatures,
    user-owned keys
    data signatures,
    user-owned keys
    app semantics live in... servers, clients servers, clients dedicated service, clients clients servers (hubs)
    blockchain no no no no yes
    monetization hosting donations services microtransactions signup, storage, microtransactions
    user base estimates
    (as of Oct 2024)
    not well defined 1M MAU, 11M-15M total 4.8M MAU, 1.2M DAU, 10.8M total 32k WAU, 15k DAU, 190k total 167k MAU, 50k DAU, 690k total, but probably much less
    server estimates
    (as of Oct 2024)
    not well defined 21k-30k ~300 PDSes, 5+ AppViews, ? relays 800-2800 19k
  • How are the different protocols translated?
  • Here are internal details on how Bridgy Fed translates user identity and events between protocols, including some like Nostr/AT Protocol that aren't launched here, or even fully implemented or thought through yet. Caveat hacker!

    In the tables below, BF is Bridgy Fed. Green parts have been implemented and running here for years, the rest are still in the early design phase.

    Here's how we translate user identity between protocols. Specifically, each cell shows how a user in a given column is identified to the protocol in a given row. These identities uniquely identify users, and are intended primarily to be machine readable and usable. (Scroll down for the equivalent table for translating human-meaningful user handles.)

    Note that Bridgy Fed generates some of these ids itself behind the scenes, notably did:plcs for Bluesky/AT Protocol and npub public keys for Nostr.

    Web ActivityPub AT Protocol Nostr
    Web URL - Fediverse profile URL https://bsky.app/profile/[handle]
    (can we avoid hard-coding bsky.app?)
    NIP-05 domain or BF user page
    WebFinger address @[domain]@web.brid.gy - @[handle]@bsky.brid.gy @[NIP-05 or npub]@nostr.brid.gy
    ActivityPub actor https://web.brid.gy/ap/[domain] - https://bsky.brid.gy/ap/[did] https://nostr.brid.gy/ap/[npub]
    AT Protocol did:plc did:plc - did:plc
    Nostr npub npub npub -

    Here's how we translate user handles (aka usernames) between protocols. Each cell shows how a user's handle in a given column is translated to the protocol in a given row. These handles are human-chosen, human-meaningful, generally unique, but may not be the primary machine-usable ids in each protocol. Scroll down to the next table for examples, up to the previous table for machine-usable ids.

    Basic is the default, enhanced requires extra setup on the user's part (or their fediverse instance's) to forward some of their /.well-known HTTP requests to Bridgy Fed.

    Web ActivityPub AT Protocol Nostr
    Web - Fediverse profile URL bare handle NIP-05 domain or BF user page
    AP address basic @[domain]@web.brid.gy - @[handle]@bsky.brid.gy @[NIP-05 or npub]@nostr.brid.gy
    enhanced @[domain]@[domain] @[handle]@[handle] @[NIP-05]
    ATP handle basic [domain].web.brid.gy [username].[instance].ap.brid.gy - [NIP-05 or npub].nostr.brid.gy
    (convert @ to .)
    enhanced bare domain bare domain bare NIP-05 domain
    (_ username)
    Nostr NIP-05 domain basic [domain]@web.brid.gy [username].[instance]@ap.brid.gy [handle]@bsky.brid.gy -
    enhanced bare domain [username]@[instance] bare handle

    Here are concrete examples:

    Web
    me.com
    ActivityPub
    @[email protected]
    AT Protocol
    me.com
    Nostr
    [email protected]
    [_@]me.com
    Web - https://instance.com/@me
    (varies by instance)
    me.com ?
    me.com
    ActivityPub basic @[email protected] - @[email protected] @me[domain.][email protected]
    enhanced @[email protected] @[email protected] @[email protected]
    @[email protected]
    AT Protocol basic me.com.web.brid.gy me.instance.com.ap.brid.gy - me.[domain.]com.nostr.brid.gy
    enhanced me.com me.com me.[domain.]com
    Nostr basic [email protected] [email protected] [email protected] -
    enhanced [_@]me.com [_@]me.instance.com [_@]me.com

    Here's how we infer the protocol for any string id. In the Format column, green parts are deterministic, ie they conclusively determine that a matching id belongs to the protocol, and yellow parts are ambiguous, ie a matching id may or may not belong to the protocol:

    Example(s) Format Network discovery
    Web user https://snarfed.org/ http(s) URL with empty path HTTP GET succeeds and returns HTML
    object https://snarfed.org/2023-05-26_50328 http(s) URL with non-empty path
    ActivityPub user https://indieweb.social/users/snarfed http(s) URL HTTP GET with AS2 conneg returns valid AS2 with Actor type
    object https://mitra.social/post/01885fad HTTP GET with AS2 conneg returns valid AS2 with non-Actor type
    AT Protocol user did:plc:abc123
    did:web:snarfed.org
    did:plc or did:web: prefix
    (TODO: domain handles)
    resolve did:plc,
    resolve did:web
    object at://did:plc:asdf/post/abc-123 at:// URI com.atproto.repo.getRecord XRPC
    Nostr user abc123... (32 chars)
    npub10hx886... (bech32)
    32 char hex or npub prefix (TODO: NIP-05 domains) NIP-65 or NIP-39 lookup
    object def456... (32 chars)
    nevent10hx886... (bech32)
    note10hx886... (bech32)
    32 char hex or nevent, note, etc prefix REQ request

    Here's how we translate events and operations between protocols, both inbound to and outbound from Bridgy Fed:

    Web ActivityPub AT Protocol Nostr
    User discovery inbound serve h-card on BF user page basic: serve WebFinger and AP actor on fed.brid.gy
    enhanced: user's site serves and redirects WebFinger to fed.brid.gy
    resolve DID, serve DID document with fed.brid.gy PDS NIP-39 (kind 0) query to BF (or other?) relay
    User discovery outbound Fetch home page, parse h-card look up WebFinger, fetch AP actor resolve DID, subscribe to PDS repo, extract profile object? discover user's relays with NIP-65, query NIP-39 to get profile
    Publish inbound webmention to fed.brid.gy deliver to fed.brid.gy inbox, user or shared receive post via firehose from relay publish event to BF relay
    Publish outbound serve on BF user page followings h-feed deliver to recipient's inbox serve commit via subscribeRepos XRPCs to subscribing relays serve to subscribers
    Follow inbound users: UI on BF user page
    code: webmention with u-follow-of
    Follow activity delivered to BF user inbox receive follow via firehose from relay user's client sends REQ to BF relay
    Follow outbound webmention with BF proxy HTML page as source deliver Follow to followee's inbox call sync.subscribeRepos on followee's PDS? discover followee's relay(s) with NIP-65, send them a REQ
    Response inbound webmention to a BF proxy page Create, Like, Announce delivered to BF user inbox receive response via firehose from relay NIP-10 response event received at BF relay or other relay
    Response outbound same as follow outbound, with the corresponding response data type
  • How are activities routed?
  • A bridge does more than just translate protocols and formats. It processes activities (events) based on domain-specific logic and semantics. The domain Bridgy Fed currently handles is public social microblogging, the kind popularized by Twitter. There are many other related social domains, with fuzzy boundaries and lots of overlap, eg forums (Reddit), questions and answers (StackOverflow), project trackers (GitHub), and many more, but here we're currently focused on microblogging.

    Even within that domain, behavior logic varies. Twitter follows are one way, but Facebook friends are bidirectional. Your Bluesky timeline (skyline) includes your followings' replies, but your fediverse timeline generally doesn't. LinkedIn...honestly I have no clue how LinkedIn works, but I'm sure it has its own logic, workfluencers and all.

    Here's what Bridgy Fed's activity router does. I've tried to make it follow "least common denominator" logic, ie do the most common and least surprising thing, and I've explicitly tried not to innovate or invent anything new here. It's a bridge, not a product, after all.

    When Bridgy Fed receives a... The router will...
    follow
    • deliver the follow activity to the followee
    • automatically send an accept activity to the follower
      (we may eventually add UX for this)
    • store the follower locally
    • generate a local notification to the follower
    unfollow
    • deliver the unfollow activity to the followee
    • deactivate the locally stored follower
    new post
    • deliver to all active stored followers
    • store the post locally
    update post
    • deliver to all active stored followers
    • update the locally stored post
    delete post
    • deliver to all active stored followers
    • mark the locally stored post deleted
    delete actor
    • deactivate their locally stored follows, to and from
    reply
    • deliver to the original post
    • store locally
    • generate a local notification to the original post's author
    repost
    • deliver to all active stored followers
    • store locally
    • generate a local notification to the original post's author
    like
    • deliver to the original post
    • generate a local notification to the original post's author