So, I find myself in a situation where I want my experience of the fediverse, and my interaction with the fediverse, to break out of the mold that casts most of the current class of fediverse servers. I want to come at it from a different direction and different architectural model to see if the differences in structure and approach make for a more adaptable experience for users and administrators of the instance.
There are lots of different descriptions1 out there on how the fediverse works and what a fediverse instance is responsible for in terms of complying with the ActivityPub protocol2 and various other protocols and conventions that have accreted around the varied instance implementations to varying degrees of interoperability and angst. If you would like to know more about the details on how ActivityPub works in theory and in practice, I beseech thee to follow the example of my fedifriend Christine Lemmer-Webber3 and post a message in the fediverse asking folk to explain it to you. You will get a lot of eager assistance based on previous experiences.
How’s The Fediverse Work Anyway?
For the purposes of this thought experiment, it’s sufficient to say that most fediverse servers provide a way for their users to post new Activities from a client, have those Activities be distributed to a user’s followers, and receive Activities from remote users, both those that are followed by local users and those that are interacting with Activities originating from local users, and since ActivityPub is very web-centric, a web-based reference of the user Activities on their profile for viewing (pending various other conditions). There’s more to it but that’s close enough to talk about what I want to talk about.
What I’d Like To Do Differently
There are dozens of existing fediverse server projects in active use currently, some of them by a handful of folks, some of them by thousands and thousands of servers, and each takes its own approach to participating in the fediverse. A large majority of them seem to focus on reproducing the experience, or parts thereof, of other formerly popular social networks of yore, and are successful to various extents based on their users’ continued use of their servers. But none of them are really approaching the fediverse from the direction I think I want to, for my own personal experience. (Some of the smallest of the projects come much closer to what I think I want than the larger projects, for reasons that will probably become clear as this post goes on.)
This post is my attempt to put down in writing some of the ideas I want to carry forward into the theoretical implementation of an ActivityPub server, MyActivityRouterKit, or MARK, and a web-based ActivityPub client, MyActivityClientKit, or MACK. I feel like these names are horrible and perfect. This is no way to brand a serious project. This is not a serious project and it needs no brand, but names are nice, so MARK and MACK it shall be, at least for the duration of this post.
So, in no particular order, here are the overall focal points I would hypothetically take if I were to undertake implementing my preferred approach to MARK and MACK.
Modular vs Monolithic
Most of the current batch of fediverse servers are highly opinionated (in *my* opinion), batteries-included type projects. They’re generally started by someone with a vision for what they want their experience to be, and they build that experience. They’re big ol’ monoliths that satisfy the requirements necessary to participate in the dance that is ActivityPub server-to-server federation, and they provide some form of API for clients to communicate with them, and they spit out some web views as well. There’s generally (but not always!) a database involved, and a bunch of storage for media attachments, and queue runners to handle the Activities being shuttled back and forth between the participating nodes. There’s generally some sort of administrative interface, on the web and/or in the form of command line tooling. There are maintenance scripts. There are logs to ship and metrics to be tracked. Roadmaps and issue trackers abound. It’s all very much a Software Project.
I’m more interested in a far less monolithic, more modular, approach. Often, an analogy is tossed out into the void: “The fediverse works kinda like email!” and it’s true, to a point. I’d like to lean into that point, frankly, and have a fedi server that works like a bare-bones mail transit agent (MTA), or more simply mail server.
Mail servers are neat. They listen for connections, and when a connection comes in, they speak the protocols, make the checks to see if the incoming traffic is something that meets their *minimum criteria for correctness*, and then hands it off to the rest of the process(es) that will decide the ultimate fate for the recently received data. Mail servers have been around for decades and decades, so being opinionated about how they should work has been going on for a long time, and lots of opinions have been built up and burned down. As such, there are many ways to solve for any particular style of mail processing that a nascent mail server admin might want to invoke. Want to have your mail server check to see if the incoming messages are spam before delivering them to your users? There are lots of great packages that take an incoming messages, apply logic to decide if they’re spam or not, and label them, passing them on to other processes that know what to do with spam and what to do with not-spam.
And there are lots of other types of processing that might take place when a mail server receives a message before the message lands in the mailbox it is intended for, if it ever gets there at all! So, MTAs usually are structured in a way that make it possible to have a processing pipeline that handles incoming messages based on the content of the messages themselves, including the metadata about that content, and so it’s a pretty flexible system. You like your anti-spam solution, I like mine, a good MTA will work with either. Sweet!
So, MyActivityRouterKit, good ol’ MARK, would approach the problem space by focusing on making sure the initial transaction – the receiving and sending of Activities to and from other ActivityPub servers – was technically correct (the best kind), and then handing the technically correct Activities off to one or more modular scripts that would examine, massage, and sort those Activities into their proper places based on the rules set up by the operator of that instance. Some instances will want more processing, some less, but all of them will need some, so concentrate on the some that they all need, and allow for multiple approaches to the some that are “correct for my needs but not for everyone”.
Not a fediverse server so much as a kit for creating a fediverse server that works the way the operator wants it to work. MARK.
Easy To Deploy
This one’s not about the fediverse’s approach to building software, but rather about how a huge swath of the world’s software developers have decided that having huge stacks of developer tooling be involved in the deployment and operation of server software is legit. It is legit, sure, if you’re willing to focus on only addressing the needs of operators comfortable with the combination of tooling you’ve selected for your project. Otherwise, every piece of your tech stack is another barrier to adoption for someone who just wants to run a thing.
So, I want MARK and MACK to be as simple as possible to deploy for your average operator. I want them to be “drop these files on your web server” simple to deploy. Simple simple. So, I’d be likely to reach for a tech stack that’s pretty ubiquitous, is widely supported by hosting providers for non-technical customers, and brings minimal barriers to adoption in tow. Yep, PHP. Good old PHP. Drop files in folder on PHP-capable web server and bingo bango bongo, your thing’s doing the thing. Probably wouldn’t even use Composer to manage any libraries I’d include – I’d just vendor them in and update dependencies when I released a new version. Rolling releases leave people on the side of the information superhighway with a flat tire as much as not. I’d rather give folk a code drop that worked together and would stay put until the next time they installed a code drop.
Easy To Modify
Did I mention PHP? It’s just a scripting language. Text files. Easy to edit. No compilation step. No minifying. No obfuscation. Text. Files.
So, I’d probably vendor in a web-based text editor, maybe even with PHP syntax highlighting, and expose the ability to modify the scripts from the operator’s web interface. Make change, save file, test change, be happy or roll back. Want to commit your modifications to a revision control system of some sort? Good idea! That should be easy to do as well, again from the web interface as much as possible.
Want to handle some Activity type I didn’t handle more than in the most generic sense? Drop in a new handler for that type and roll on, friend.
But another key aspect of making something “easy to modify” means it also needs to be “easy to comprehend”. So, MARK and MACK would be heavily documented throughout its code base, in a narrative comment style that addresses both the technical and the conceptual design and implementation of each part of the processing scripts, in a tone similar to that taken by Terrence Eden’s single-file ActivityPub server in PHP here: https://gitlab.com/edent/activitypub-single-php-file but maybe even more verbosely! I’m a chatty person!
Aggressive Interoperability
So, what kind of batteries do I want in *my* fediverse server? I want battery flexibility. I want to adopt support for things other ActivityPub servers already support, and I want to be able to play with and prototype support for things other ActivityPub servers don’t yet support. I want to adopt Mastodon’s content warnings (to an extent) and GoToSocial’s interaction policy support, and the Misskey-family emojo reaction support, and so on and so forth. I want to support PeerTube videos and Pixelfed images and albums, and Funkwhale playlists, and on and on and on. I want it to be a relatively approachable task to look at how some Activity type is being propagated across the network and implement a handler for accepting and displaying that Activity type in a way that pleases me as a user and me as an operator and me as a community builder, and I don’t want to have to empanel a committee to decide how to approach doing so.
Excessively Sparse
And lastly, I want it to be as small and svelte as possible. Just enough code, just barely, to do the things I want it doing, and no extra baggage. Life’s already complicated, let’s work on making it less so on the optional bits we choose to do, eh? No reason to over-engineer this – scale is a trap.
So, Will It Happen?
Who knows? I clearly have Thoughts and Opinions. I’ve a history of building stuff like this when I’ve the time and drive. It could happen. It might not!
You could do it! I would not be upset. I might not be impressed, either! Don’t do it to impress me, do it because you want your own kit for building your fediverse experience.
If I end up doing something like this, you’ll probably hear about it. Maybe not! Life is weird.
Thanks for reading!