Evan Prodromou

@evanprodromou.socialwebfoundation.org.ap.brid.gy

Research Director at the Social Web Foundation. Current editor of the ActivityPub and Activity Streams 2.0 specifications at the Social Web […] 🌉 bridged from ⁂ https://socialwebfoundation.org/author/evanprodromou/, follow @ap.brid.gy to interact

About 14 years ago, I created a webfinger package for NodeJS. At the time, NodeJS was only a few years old. I had created pump.io as a new social networking engine and the successor to StatusNet. I needed a client for webfinger lookup -- the process of converting a user@domain.tld handle to a […]

webfinger package for NodeJS

About 14 years ago, I created a webfinger package for NodeJS. At the time, NodeJS was only a few years old. I had created pump.io as a new social networking engine and the successor to StatusNet. I needed a client for webfinger lookup — the process of converting a _user@domain.tld_ handle to a API endpoint for processing messages — and there wasn’t one for NodeJS, so I made it. It is kind of an antique — very old callback-style code that has its own HTTP processing system. It supported the older version of Webfinger, RFC 6415, using XML for the data format. It also supported the (at that time) new Webfinger specification, RFC 7033. Since its last release in 2013, version 0.4.2, I hadn’t touched the project. It’s just been languishing in the npm repository, squatting on the “webfinger” package name, and collecting dust. The Webfinger RFC was published, ActivityPub was standardized, and the Fediverse grew and grew, without a single change to the package. I realized I was sitting on this package a couple of years, ago, and I’ve been wanting to get a new version out. This week, I just did it. I ripped out all the legacy support for RFC 6415, upgraded the tests to use the Node test runner, switched from callback style to async/await, changed to ESM modules, and changed the format to StandardJS. I also added a little utility method, so it’s easier to look up links in the JRD file that is returned. Now, to get an ActivityPub actor, you just do this: const types = [ 'application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ] const actorId = (await webfinger('user1@foo.example')).link('self', types)?.href I think the dependencies are low enough that you can use this version of the library from browser apps, although I haven’t tried it yet. Anyway, I published version 0.5.1 today. I hope it provides some value to other people working on Fediverse software.

socialwebfoundation.org

One of the requests I (Evan) have heard often over the years about ActivityPub is to make publishing on the Fediverse as easy as publishing with RSS. To make an RSS feed for a person or a site, a publish provides, dynamically or even statically, a single file, with a simple format, and makes it […]

Static ActivityPub Publishing

One of the requests I (Evan) have heard often over the years about ActivityPub is to make publishing on the Fediverse as easy as publishing with RSS. To make an RSS feed for a person or a site, a publish provides, dynamically or even statically, a single file, with a simple format, and makes it available over the Web. Other people’s feed reader software can download the feed and show the user either the full content of the site, or enough of a summary to get the user to click a link and read in your browser. So… why can’t ActivityPub be like that? Make a feed, and let others read it if they want to? The good news is, _it can._ ActivityPub defines an entire read-only structure for actors, content, and activities. Pushing content to other servers is _entirely optional_ — you can just tell other servers that you don’t accept remote content, and they won’t push it. The read-only interface to ActivityPub is rich and extensible — it covers content like text, images, video and audio, but also activities like liking, sharing, and replying. It’s not quite as simple as RSS — it requires a lot more, smaller files — but it’s pretty straightforward. The bad news is that most widely-used ActivityPub software doesn’t recognize read-only ActivityPub feeds. Most ActivityPub servers expect to send messages to every actor, and to receive messages in reply. They don’t have internal facilities to check ActivityPub feeds regularly for new content and activities. This isn’t just a technical issue; it’s also an adoption issue. If implementing ActivityPub requires all the infrastructure of our message-passing services — queues, signatures, filtering, fanout — it inhibits software developers and publishers from experimenting with the protocol. Implementing RSS can take a day or maybe a week of developer work. Implementing ActivityPub’s federation protocol can take months. Which one is going to be done in a hackday or a medium T-shirt-size sprint task, and which one is going on the back-back-back-backlog? To make it easier to understand and support this proper subset of ActivityPub, I published FEP-b06c: ActivityPoll last summer. (“Poll” is in contrast to “publish” — emphasizing the read-only structure.) It’s a profile of ActivityPub, identifying parts of the ActivityPub spec that will work, or not, with a static, read-only ActivityPub publisher. It also includes new terms to easily identify a read-only ActivityPub actor, as well as a way to declare how often a feed is updated (very useful for limiting the load on both the reader and the server sides). In order to test the profile, and identify shortfalls, I implemented a plugin for the static site generator (SSG) software, Jekyll. Using a static site generator keeps this process honest — there’s no temptation to add just a teensy bit of dynamic content generation; it has to be entirely static. If we can show interoperability with actors implemented with an SSG, we’ve shown that static ActivityPub publishing is truly possible. The plugin is called jekyll-activitypub-static (there’s already a jekyll-activity-pub plugin, which uses off-site dynamic endpoints to implement the federation protocol, so this one emphasizes that it’s static). It’s in the rubygems.org repository, so you can just add the gem name to your Gemfile for your Jekyll site, and it should install correctly. The configuration is pretty straightforward, and has pretty reasonable fallbacks, but you can tweak it to get more specific features. I’ve got an example actor on GitHub Pages at @evanp . You can search for it in Mastodon, and view the profile, but you can’t follow it directly. Other front ends can view it more directly — please tell me if yours can! If you’ve got a Jekyll site, please try out jekyll-activitypub-static and let me know what you think. Fair warning — the Webfinger support depends on having your site deployed at the root of the domain. There are probably some ways to work around that — let me know if you find one! If you have changes or enhancements you think can be made, let me know. And if you’ve got a full-featured implementation of the ActivityPub federation protocol, please consider implementing a polling structure for static actors. FEP-b06c covers most of the caveats, but please feel free to leave a comment if you find another gotcha. I’ll be right in there with you — I’m going to implement it in onepage.pub and activitypub.bot. Thanks to everyone who has commented on FEP-b06c, and to people who’ve tried and contributed to jekyll-activitypub-static. I look forward to more implementations!

socialwebfoundation.org

On Friday, August 14, 2026 at the HOPE conference in New York City, we'll be running a workshop to help new people join the Fediverse. This is an exciting first for us, and we'd love your help making it a great experience. Here's what we need: Open-registration Fediverse servers that are […]

Help HOPE Hackers Hop Onto the Fediverse

On Friday, August 14, 2026 at the HOPE conference in New York City, we’ll be running a workshop to help new people join the Fediverse. This is an exciting first for us, and we’d love your help making it a great experience. Here’s what we need: * **Open-registration Fediverse servers that are welcoming the HOPE audience.** The HOPE conference welcomes people involved in information security, digital rights, as well as experimentation with radio, electronics, and other tech. It also usually has people from New York, New Jersey, and elsewhere in the Atlantic seaboard. If you know of servers that would welcome this kind of new member, please let us know! Even if the server isn’t open registration, but can accommodate new users on the day of the workshop, we’d love to coordinate. * **First-timer Collections.** Do you know of a good starter follow pack that new users might enjoy? Especially if their interests overlap with the HOPE audience. Just some names to follow is a big help, too. * **New user tips**. What helps people get started on the Fediverse? What helps them stay engaged? * **Volunteers**. Will you be at HOPE? Want to meet interesting people and help them get started with the Fediverse? It should be fun and easy. Please reply to this post with ideas or contact info. This is going to be fun!

socialwebfoundation.org

I (Evan) will be at the Wikimedia Hackathon 2026 in Milan, Italy this weekend (May 1-4). I'm especially interested in how we can connect Wikimedia projects and content to the Social Web using ActivityPub. I'll be holding a session on the topic on Sunday May 3 at 9AM, but I'll also be available […]

Social Web Foundation at Wikimedia Hackathon

I (Evan) will be at the Wikimedia Hackathon 2026 in Milan, Italy this weekend (May 1-4). I’m especially interested in how we can connect Wikimedia projects and content to the Social Web using ActivityPub. I’ll be holding a session on the topic on Sunday May 3 at 9AM, but I’ll also be available for discussions throughout the weekend. My hacking project plan is to make an ActivityPub object server for films. There are about 343,000 films in Wikidata, which compares pretty favourably with the 740,000 films in IMDB. There is a JSON-LD interface to Wikidata, but the types used don’t match up with ActivityPub types like Video. So, like places.pub, I’ll set up movies.pub to share an ActivityPub object for every Q-item for a movie, as well as a search endpoint to find films by name. If I get ahead of the project and I’m not too jet-lagged, I’d like to add an ActivityPub API app to “check in” to a movie that you’re watching (and maybe give a little review). Similar to checkin.swf.pub with places! If you’re at #wmhack this weekend, please come say hi. I love talking about Wikimedia projects and the open social web.

socialwebfoundation.org

The call for proposals is open for the COSCUP Fediverse track in Taipei, Taiwan. ActivityPub-related software, including server and client implementations, are great topics for the event. COSCUP ("Conference for Open Source Coders, Users, and Promoters") is the FOSDEM of East Asia. Run by the […]

Fediverse Track at COSCUP: Call for Proposals

The call for proposals is open for the COSCUP Fediverse track in Taipei, Taiwan. ActivityPub-related software, including server and client implementations, are great topics for the event. COSCUP (“Conference for Open Source Coders, Users, and Promoters”) is the FOSDEM of East Asia. Run by the Open Source community in Taiwan, it brings together people excited about FOSS across the region. For the first time, this year, members of the Korean ActivityPub developer community FediDev KR are joining up with FediLUG of Japan to program and run a Fediverse track at COSCUP. This has the potential to be a huge step forward for the Fediverse developer community. Although many major projects, like Fedify and Misskey, are created and promoted in East Asia, distance and language barriers make it hard for East Asian devs to participate in European and North American in-person events. The Fediverse track is open to proposals about ActivityPub implementations, clients for ActivityPub platforms, ancillary services, libraries and toolkits. But also, as at FOSDEM, talks about the human aspects of Fediverse technology, like moderation, policy and governance, are welcome and encouraged. This event looks like it will cover as much interesting conceptual space as its twin at FOSDEM. Hong Minhee, hongminhee@hollo.social, was one of the main speakers at FOSDEM’s Social Web devroom this year. Their talk about Fedify was important, but even more important was their effort to bridge the gap between Asia’s and Europe’s Fediverse development communities. I (Evan) hope that COSCUP brings together many Asian developers, but I also hope that North American and European individuals and teams put in proposals as well. Knitting together these two important communities on the Fediverse requires effort from both sides. That’s why I’m applying to speak (about ActivityPub 1.1), and why I hope to see many familiar faces among the new ones in Taiwan.

socialwebfoundation.org