Fedify: ActivityPub server framework's avatar

Fedify: ActivityPub server framework

@fedify@hollo.social

9 following1,123 followers

:fedify: Fedify is a TypeScript library for building federated server apps powered by ActivityPub and other standards, so-called fediverse. It aims to eliminate the complexity and redundant boilerplate code when building a federated server app, so that you can focus on your business logic and user experience.

@me@changkyun.kim
ActivityPub와 Fedify로 개인 웹사이트를 Fediverse에 연결하고 댓글과 반응을 주고받게 만든 기록입니다.

이번에 changkyun.kim에 ActivityPub을 붙였습니다. 이제 이 사이트는 Fediverse에서 @me@changkyun.kim이라는 actor로 보입니다.

하고 싶었던 일은 단순했습니다. 블로그 글을 올렸을 때 Mastodon이나 Misskey 같은 곳에서 글을 찾고, 답글을 달고, 좋아요나 이모지 반응을 보낼 수 있게 만들고 싶었습니다. 별도 로그인이나 회원가입을 만들고 싶지는 않았습니다. 각자 원래 쓰던 Fediverse 계정으로 반응하면, 제 사이트는 그 반응을 받아서 글 아래에 보여주면 된다고 생각했습니다.

처음부터 깔끔하게 된 것은 아니었습니다. 한동안은 ActivityPub을 직접 구현해 보려고 했고, 나중에는 Fedify를 붙이는 쪽으로 방향을 바꿨습니다. 이 글은 그 과정에 대한 기록입니다.

ActivityPub과 Fedify를 붙였습니다

간단히 설명하면, ActivityPub은 네트워크에서 일어나는 어떤 액티비티를 상호 약속된 프로토콜에 따라 이메일처럼 주고받으며 전파하고 상호작용하는 API 모음이자 규칙이라고 할 수 있습니다.

W3C는 2018년 1월 23일 ActivityPub을 Recommendation으로 발표했습니다. 문서에서는 ActivityStreams 2.0 기반의 분산형 소셜 네트워킹 프로토콜이라고 설명합니다.

https://www.w3.org/TR/activitypub/

처음에는 필요한 endpoint를 직접 만들면 될 것 같았습니다. WebFinger로 계정을 찾게 하고, actor 문서를 내보내고, inbox와 outbox를 만들면 된다고 생각했습니다.

실제로 하나씩 만들 수는 있었습니다. 다만 곧 처리할 일이 많아졌습니다. 글을 Article 객체로 내보내야 했고, Follow, Create, Like, Undo, Delete 같은 활동을 구분해야 했습니다. 다른 서버로 활동을 보낼 때는 HTTP Signature도 맞춰야 했고, shared inbox도 신경 써야 했습니다.

직접 해 본 것은 도움이 됐습니다. ActivityPub에서 actor, object, activity가 어떻게 이어지는지 감을 잡을 수 있었습니다. 하지만 개인 웹사이트에 붙여서 계속 운영하려면 직접 구현한 코드가 너무 커질 것 같았습니다.

그래서 Fedify를 붙였습니다. Fedify는 ActivityPub 서버 앱을 만들기 위한 TypeScript 라이브러리입니다. 공식 사이트에서는 Fediverse 서버 앱을 만들기 위한 ActivityPub server framework라고 소개합니다.

https://fedify.dev/

Fedify를 붙이고 나서는 제가 정해야 하는 부분이 조금 분명해졌습니다. 이 사이트의 actor는 누구인지, 어떤 글을 outbox에 내보낼지, inbox로 들어온 활동을 어떻게 저장할지 정하면 됐습니다.

물론 구현이 사라진 것은 아닙니다. 지금도 댓글, 반응, following feed를 저장하는 테이블이 있고, Cloudflare Workers의 KV와 Queue도 사용합니다. 다만 직접 ActivityPub의 모든 부분을 맞추는 코드보다는, 이 사이트의 콘텐츠와 반응을 어떻게 다룰지에 더 집중할 수 있었습니다.

현재 이 사이트는 블로그 글과 앱 글을 ActivityPub Article로 내보냅니다. 누군가 @me@changkyun.kim을 팔로우하면 Follow를 받고 Accept를 보냅니다. 연결된 actor들의 공개 글은 /following/에서도 볼 수 있게 했습니다.

댓글과 반응은 Fediverse 계정으로 남깁니다

블로그 글 아래에는 ActivityPub 댓글 안내가 있습니다. Mastodon 같은 클라이언트 검색창에 글 주소를 붙여 넣고, 검색 결과에서 이 글을 연 뒤 답글을 쓰면 됩니다.

그 답글은 원격 서버에서는 평소와 같은 답글입니다. 제 사이트에서는 inbox로 들어온 Create 활동을 읽고, 어느 글에 대한 답글인지 확인한 뒤 댓글로 저장합니다. 화면에는 작성자의 이름, 프로필 이미지, 원래 글 주소를 함께 보여줍니다.

이 방식이 마음에 들었던 이유는 로그인 기능을 따로 만들지 않아도 된다는 점입니다. 댓글을 쓰는 사람의 신원은 이미 각자의 Fediverse 서버에 있습니다. 제 사이트는 그 신원을 새로 만들지 않고, 도착한 답글을 글 아래에 보여주기만 합니다.

Like가 들어오면 좋아요 반응으로 저장합니다. EmojiReact가 들어오면 이모지 반응으로 저장합니다. 글 아래에서는 이모지와 개수를 모아서 보여줍니다.

모든 서버가 같은 방식으로 반응을 보내지는 않습니다. 특히 이모지 반응은 서버마다 차이가 있습니다. 그래서 일단 받을 수 있는 것은 받아 두고, 화면에는 확인된 값만 보여주도록 했습니다.

이 부분도 댓글과 비슷합니다. 제 사이트에서 별도의 반응 버튼을 새로 만든 것이 아닙니다. 누군가 자기 Fediverse 클라이언트에서 누른 반응이 제 사이트에도 도착하게 만든 것입니다.

atproto도 생각해 봤습니다

중간에 atproto도 생각해 봤습니다. 좋고 나쁨을 비교하려던 것은 아니었습니다. 제가 하려던 일이 무엇인지 놓고 보면 ActivityPub 쪽이 더 직접적이었습니다.

atproto 문서에서는 PDS, Relay, AppView를 주요 구성요소로 설명합니다. 사용자의 데이터는 PDS에 있고, Relay는 여러 PDS의 변경 이벤트를 모으고 다시 흘려보내며, AppView는 그 데이터를 읽어서 실제 앱 화면과 기능을 만듭니다.

https://atproto.com/guides/overviewhttps://atproto.com/guides/the-at-stack

atproto로도 나만의 PDS를 만들고, Bluesky 네트워크의 Relay, 예전 표현으로는 BGS에 가까운 계층으로 글 데이터를 배달하는 식의 구성을 생각할 수는 있습니다. 하지만 그 경우에는 목적이 조금 달라집니다. 저는 새로운 소셜 네트워크나 앱을 만들고 싶었던 것이 아니었습니다.

제 목표는 이미 제가 소유한 글, 특히 블로그의 Article을 분산된 연합우주에 배달하는 것이었습니다. 구독자가 자기 Fediverse 계정으로 편하게 받아보고, 답글이나 좋아요나 이모지 반응을 보낼 수 있으면 됐습니다.

이 블로그는 Nuxt Content를 사용합니다. 소스코드와 블로그 콘텐츠를 포함한 거의 모든 소스가 git 저장소에 있습니다. 글은 Markdown 파일이고, 배포 대상도 이 저장소에서 만들어집니다. 이 구조는 제가 원하는 만큼 포터블합니다.

atproto로 같은 일을 하려면 제가 쓸 PDS를 준비해야 하고, 그 안에 어떤 collection과 lexicon으로 글을 표현할지도 정해야 합니다. 거기서 끝나는 것도 아닙니다. 중앙 네트워크를 통해 배달된 collection을 실제로 읽고 보여줄 클라이언트나 AppView도 필요합니다. 저는 그 부분까지 새로 만들고 싶지는 않았습니다.

그래서 이번 작업에서는 ActivityPub이 더 맞았습니다. 이미 있는 글을 Article로 내보내고, 이미 있는 Fediverse 클라이언트에서 구독하고 반응할 수 있게 만드는 쪽이 제 목적에 가까웠습니다.

아직은 써 보면서 보고 있습니다

이번 작업을 하고 나서도 이 사이트의 기본 구조는 그대로입니다. 글은 Nuxt Content 파일로 남고, 주소도 제 도메인 아래에 있습니다. 달라진 것은 글 바깥에서 일어난 반응을 다시 받아볼 수 있게 됐다는 점입니다.

직접 구현해 보던 때에는 생각보다 손봐야 할 부분이 많았습니다. Fedify를 붙인 뒤에는 맡길 수 있는 부분이 생겼고, 제가 직접 정해야 하는 부분도 더 잘 보였습니다. 개인 웹사이트를 Fediverse에 붙이는 작업 범위도 그만큼 줄었습니다.

아직 운영하면서 더 봐야 할 부분은 있습니다. 서버마다 ActivityPub 구현이 조금씩 다르고, 반응이 항상 같은 형태로 오지도 않습니다. 그래도 지금 정도면 제가 원했던 흐름은 만들어졌습니다. 글은 제 사이트에 두고, 대화는 각자의 Fediverse 계정으로 이어질 수 있게 됐습니다.

atproto.com

The AT Stack - AT Protocol Docs - AT Protocol

Components of the AT Protocol Stack.

Fedify 2.2.0 is out! This release finally adds client-to-server (C2S) outbox listener support, proper HTTP 410 Gone responses for deleted actors via Tombstone, new integrations for SolidStart and Nuxt, and interoperability fixes for Lemmy and Pixelfed. Three new end-to-end tutorials also landed alongside a custom collections cookbook.

https://github.com/fedify-dev/fedify/discussions/733

github.com

Fedify 2.2.0: C2S outbox listeners, `Tombstone` support, SolidStart and Nuxt integrations, and three new tutorials · fedify-dev/fedify · Discussion #733

Fedify is a TypeScript framework for building ActivityPub servers. It implements federation details such as HTTP Signatures, JSON-LD processing, WebFinger, inbox and outbox routing, and activity de...

Fedify 2.2.0 is out! This release finally adds client-to-server (C2S) outbox listener support, proper HTTP 410 Gone responses for deleted actors via Tombstone, new integrations for SolidStart and Nuxt, and interoperability fixes for Lemmy and Pixelfed. Three new end-to-end tutorials also landed alongside a custom collections cookbook.

https://github.com/fedify-dev/fedify/discussions/733

github.com

Fedify 2.2.0: C2S outbox listeners, `Tombstone` support, SolidStart and Nuxt integrations, and three new tutorials · fedify-dev/fedify · Discussion #733

Fedify is a TypeScript framework for building ActivityPub servers. It implements federation details such as HTTP Signatures, JSON-LD processing, WebFinger, inbox and outbox routing, and activity de...

@hongminhee@hollo.social

The official Awesome Fedify site is now live:

http://awesome.fedify.dev/

It brings together real-world Fedify projects, packages, examples, tutorials, and talks in one place.

If you know a good resource we should list, contributions are welcome:

https://github.com/fedify-dev/awesome-fedify

github.com

GitHub - fedify-dev/awesome-fedify: Curated list of Fedify-related resources

Curated list of Fedify-related resources. Contribute to fedify-dev/awesome-fedify development by creating an account on GitHub.

We're working on a new for : Building a Federated Blog with Astro!

It walks you through creating a hybrid blog—static Markdown posts powered by content collections, with federation layered on top. By the end, your blog will be followable from Mastodon, send Create/Update/Delete activities when you publish or edit posts, and display replies as comments.

Preview the draft here: https://d180af62.fedify.pages.dev/tutorial/astro-blog.

We'd love your feedback—especially if you spot anything incorrect, unclear, or missing. Please leave comments on the GitHub PR #695 or issue #691.

github.com

Build federated blog example and tutorial (Astro + Bun) · Issue #691 · fedify-dev/fedify

Sub-issue of #99. Deliver the federated blog scenario as a paired example repository and fedify.dev tutorial, as set in #99 (comment). Scenario A single-author federated blog where posts are author...

Naru, the Korean version of , reportedly added an implementation in just an hour using . If you also want to implement ActivityPub quickly, give Fedify a try!

https://hackers.pub/@jihyeok/019da3d9-45b8-7629-96a8-b26bd62867c2

hackers.pub

Naru (Korean Neocities) gains ActivityPub support thanks to Fedify! Now, you can follow Naru personal homepages on the Fediverse, and receive updates at most once a day per website. For example, if you want to receive updates for https://yang.naru.pub, you can simply folllow @yang@naru.pub. I believe this is a significant improvement over polling websites and an effective way to stay connected with the indie web community.

Naru (Korean Neocities) gains ActivityPub support thanks to Fedify! Now, you can follow Naru personal homepages on the Fediverse, and receive updates at most once a day per website. For example, if you want to receive updates for https://yang.naru.pub, you can simply folllow @yang@naru.pub. I believe this is a significant improvement over polling websites and an effective way to stay connected with the indie web community.

@jihyeok@hackers.pub · Reply to Jihyeok Seo

Naru (Korean Neocities) gains ActivityPub support thanks to Fedify!

Now, you can follow Naru personal homepages on the Fediverse, and receive updates at most once a day per website. For example, if you want to receive updates for https://yang.naru.pub, you can simply folllow @yang@naru.pub.

I believe this is a significant improvement over polling websites and an effective way to stay connected with the indie web community.

yang.naru.pub

팀 양나루

@jihyeok@hackers.pub · Reply to Jihyeok Seo

Naru (Korean Neocities) gains ActivityPub support thanks to Fedify!

Now, you can follow Naru personal homepages on the Fediverse, and receive updates at most once a day per website. For example, if you want to receive updates for https://yang.naru.pub, you can simply folllow @yang@naru.pub.

I believe this is a significant improvement over polling websites and an effective way to stay connected with the indie web community.

yang.naru.pub

팀 양나루

@hongminhee@hollo.social

Significant performance improvements are expected in today's latest Fedify patch releases (v1.9.9, v1.10.8, v2.0.12, and v2.1.5).

Fedify security updates: 1.9.7, 1.10.6, 2.0.10, and 2.1.3

If you use Fedify, update to a patched release now. A high-severity denial-of-service vulnerability (CVE-2026-34148) affects Fedify's remote document loader and authenticated document loader. Both follow HTTP redirects without a redirect limit or loop detection. An attacker-controlled server can return a redirect loop for a keyId or actor URL fetch, causing a single inbound ActivityPub request to keep issuing outbound requests until the fetch times out.

All versions up to and including 2.1.0 are affected. Patched releases are 1.9.7, 1.10.6, 2.0.10, and 2.1.3. Update with your package manager:

npm update @fedify/fedify
yarn upgrade @fedify/fedify
pnpm update @fedify/fedify
bun update @fedify/fedify
deno update @fedify/fedify

After updating, redeploy. If you run other Fedify-based servers, update those too.

Thanks to Abhinav Jaswal for the report and responsible disclosure. Disclosure was coordinated with Ghost so they had time to ship their update.

If anything is unclear, ask below.

ghost.org

Ghost: The best open source blog & newsletter platform

Beautiful, modern publishing with email newsletters and paid subscriptions built-in. Used by Platformer, 404Media, Lever News, Tangle, The Browser, and thousands more.

@sabrinkmann@hachyderm.io

My first PR has been merged into the main branch of the @fedify project! It's the first step in integrating into Fedify. The next step is to build on the software.
Thank you, @hongminhee, for your patience and work!
I learnt a lot about JSON-LD. I still think there is more for me to learn...

@botkit@hollo.social

BotKit 0.4.0 is out! This release adds @fedify/botkit-postgres, a PostgreSQL-backed repository for deployments where SQLite isn't enough; a remote follow button on the bot profile page, so visitors can follow directly without manually searching from their own instance; and Session.republishProfile(), which lets you push profile changes to followers without waiting for the next post. It also upgrades the underlying Fedify dependency to 2.1.2, with a few small breaking API changes.

Full release notes:

https://github.com/fedify-dev/botkit/discussions/20

github.com

BotKit 0.4.0: PostgreSQL repository, remote follow button, and Fedify 2.x upgrade · fedify-dev/botkit · Discussion #20

We're pleased to announce BotKit 0.4.0. This release brings a PostgreSQL repository for production deployments, a remote follow button in the built-in web interface, a new API for broadcasting prof...

Fedify 2.1.0 is out!

The highlight of this release is onUnverifiedActivity(), a long-requested hook that lets you intercept inbound activities whose signatures couldn't be verified, instead of silently returning 401 and letting remote servers retry forever. Great for handling Delete activities from permanently gone actors.

Also new: full RFC 9421 Accept-Signature negotiation on both outbound and inbound paths, GoToSocial interoperability fixes, @fedify/mysql for MySQL/MariaDB backends, @fedify/astro for Astro integration, and fedify lookup --recurse for following reply chains.

Release notes: https://github.com/fedify-dev/fedify/discussions/642

github.com

Fedify 2.1.0: Unverified activity hooks, RFC 9421 negotiation, MySQL support, and Astro integration · fedify-dev/fedify · Discussion #642

Fedify is a TypeScript framework for building ActivityPub servers that participate in the fediverse. It handles the heavy lifting of federation—HTTP Signatures, JSON-LD processing, WebFinger, and m...

@sabrinkmann@hachyderm.io · Reply to Samuel Brinkmann

Wir sollten „Public Money = Public Social Media” also mehr pushen.
Habt Spaß und wenn ihr könnt, baut doch etwas mit z. B. @fedify oder @botkit.
Damit das Ganze hier aber wirklich skaliert, braucht es schlichtweg mehr Geld. Natürlich auch mehr Strukturen und Spezifikationen. Dass hier überhaupt etwas gebaut wird, ist schon großartig. Im Ehrenamt lässt sich nur schwer eine Alternative zu Big Tech aufbauen, wenn man möchte, dass ein Großteil der Bevölkerung Lust hat, diese Anwendungen zu benutzen. Geschweige vom Onboarding, auch auf dem Platten land.
Wer von Open Source spricht, sollte beim Fediverse Funding nicht schweigen.

Hier noch einmal eine Linkliste von Tools:
- Ihr habt Bock auf hübsche Wraps-Grafiken für euren Account: mastodon-wrapped.playground.54
- Ihr wollt eure Account-Einstellungen checken: mastodon-account-checker.playg
- Ihr wollt wissen, welche Organisationen schon auf Mastodon sind (täglich frisch aktualisiert): mastodon-account-checker.playg
- Jede Konferenz/Treffen braucht ein Hashtag und eine fediwall.de/
- Tägliche coole Geschichtlichen Wikipedia Links gibt es hier: @heute_vor

CTA
Seid erfolgreich im Fedvierse
+1: Public Money = Public Social Media
Baut Bots und föderierte Dienste mit Fedify und Botkit
Für die Adoption der “Massen” braucht es mehr Geld in Software und Community
Looking @ you Land SH / Bund / EU
Links Tools: @sabrinkmann@hachyderm.io
ALT text

CTA Seid erfolgreich im Fedvierse +1: Public Money = Public Social Media Baut Bots und föderierte Dienste mit Fedify und Botkit Für die Adoption der “Massen” braucht es mehr Geld in Software und Community Looking @ you Land SH / Bund / EU Links Tools: @sabrinkmann@hachyderm.io

@hongminhee@hollo.social

I've been thinking about adding federation health monitoring to —not as a separate data store or custom API, but by extending the existing integration. The idea is to expose delivery outcomes, signature verification failures, and per-remote-host error rates as OpenTelemetry metrics alongside the spans Fedify already emits. If you already have a Prometheus or Grafana setup, you'd get federation observability basically for free. Circuit breaker behavior (temporarily skipping a remote server that's been consistently unreachable) could surface as OpenTelemetry events, keeping everything in the same trace context rather than scattered across separate logs.

Does this sound useful to you? I'm curious whether people building on Fedify—or running federated servers in general—would actually reach for this, and what kinds of things you'd most want to observe. Happy to hear any thoughts.

@julian@fietkau.social · Reply to Julian Fietkau

(Disclosure: Using the name and logo of Encyclia – symbolically, since Encyclia is not a legal entity – I have an active monthly donation to @fedify on OpenCollective. However, I do not believe that this is getting me any preferential treatment, and in my observation the Fedify project treats all contributors and downstream implementers with equal respect.)

@julian@fietkau.social

Seems as good a day as any to thank @hongminhee and team for the exemplary work on @fedify. Following Fedify's big 2.0 release, my two largest interoperability pain points in @encyclia can be fixed. 🙂

github.com/fedify-dev/fedify/i means that people using @gotosocial will finally be able to follow @encyclia accounts soon (whenever I finish the upgrade).

github.com/fedify-dev/fedify/i will let me (and others) handle more account resolution edge cases and reduce failure mode traffic after Fedify 2.1 is out.

github.com

Improve handling of activities signed by non-resolvable actors · Issue #472 · fedify-dev/fedify

Summary Fedify currently cannot receive activities signed by non-fetchable actors. The HTTP 401 errors it emits in response to such actors cause remote servers to retry delivery of the same activit...

@erlend_sh@socialhub.activitypub.rocks

Jiwon (@z9mb1), one of our core contributors, drew a Fedify dino! How cute!

https://oeee.cafe/@z9mb1/2b5b0baf-466b-4c65-a1e0-d3588f0666f4

oeee.cafe

Fedify dino for notice

https://kre.pe/CKwN This is a paid request :) fediverse logo was attached afterwards.

@z9mb1@oeee.cafe

Fedify dino for notice

https://kre.pe/CKwN This is a paid request :) fediverse logo was attached afterwards.

Fedify dino for notice
ALT text

Fedify dino for notice

@z9mb1@oeee.cafe

Fedify dino for notice

https://kre.pe/CKwN This is a paid request :) fediverse logo was attached afterwards.

Fedify dino for notice
ALT text

Fedify dino for notice

@hongminhee@hollo.social

Started laying out a rough plan for implementing FEP-ef61: Portable Objects in —server-independent identities backed by , multi-server replication, and client-side signing. It's going to be a long road (13 tasks across 5 phases, with a few open questions that need answering before we even begin), but I think it's worth doing right.

https://github.com/fedify-dev/fedify/issues/288#issuecomment-3971459585

github.com

FEP-ef61: Portable Objects · Issue #288 · fedify-dev/fedify

Add support for FEP-ef61 for creating server indepent fediverse applications This FEP are depend on 8b32 which already available in Fedify

@icco@merveilles.town

Over the weekend, I created robot.villas using @fedify 2.0. Not knowing how activitypub worked made this a lot harder than I expected, but did get there in the end.

Each bot mirrors an RSS feed. @nyt_travel as an example. You can add your RSS feed for funzies at github.com/icco/robot.villas/b

Let me know if you run into any issues with my new little bot farm of news.

github.com

robot.villas/feeds.yml at main · icco/robot.villas

RSS to Mastodon Bridge. Contribute to icco/robot.villas development by creating an account on GitHub.

@hongminhee@hollo.social

Hi and developers!

I'm currently working on interoperability testing for and , and I need a account to test federation with their implementation.

Since there aren't many open public Bonfire instances available, I was wondering if any Bonfire instance admins out there would be willing to grant me a test account? It would be a huge help for improving interop! Let me know if you can help. Thanks!

@thisismissem.social@bsky.brid.gy

The really cool thing about this new architecture is that it can enable Client to Server architecture for AP with fedify (maybe vocab packages could be used in the browser too!)