the dawn of rss feeds
The web had a simple promise: any site could publish a feed, anyone could subscribe, and nobody in the middle got to decide what you saw. RSS made that work for twenty years. What it never had was the conversation. You read someone's post in your reader, but replying means going to that person's platform. Suddenly you're back inside the walled garden RSS was meant to avoid.
Social networks solved the conversation and threw away the rest. The feed belongs to someone else. An algorithm decides the order. Your identity is a username the platform lends you and can take back. Leaving one network means starting from nothing on another, because what you wrote and the people who followed you stayed behind.
RSS Expert wants both things at once: the openness of RSS and the conversation of social networks, without an owner standing in the middle. You read feeds as usual. When you reply, that reply is published in your own feed, with a link to the original post. Nothing is written on somebody else's server. The other side discovers the reply because it's in the feed and because the system sends a Webmention.
The conversation happens, but it remains yours, at your address.
What it is
One static binary, one SQLite file, one container.
The only JavaScript is a twenty-line island that reveals a "new post" notice. Every page works without it. There's no CSS framework, no build step for the assets, and no separate database server to bring up. That's deliberate. One person should be able to run the whole thing on a small server and understand all of it.
These ideas hold up everything else.
Provenance is first-class information
Most systems store "this post exists." This one stores "this post was seen in this form, from this source, at this time, and I chose this version for this reason."
A post arriving through two paths isn't overwritten. Both observations remain recorded, and convergence chooses a winner deterministically while showing why. The timeline separates what was written here from what arrived from elsewhere, and it never forgets where something came from.
The Where it went screen shows every feed carrying one of your posts and every notification that was sent, including the ones that failed.
Your domain is your identity
You prove that a site belongs to you using rel=me and an h-card verified in both directions. It becomes your name in the system.
It isn't an account somebody lends you.
Federation isn't optional
It's the point. Being open and alone isn't very useful. The system speaks the protocols other open networks already speak instead of inventing its own.
Who it talks to
On the RSS and IndieWeb side, everything works without anybody else having to run this same program:
- It reads RSS 2.0, Atom, JSON Feed, h-feed, and OPML.
- It publishes a per-user feed, a site-wide feed, and a reply feed for each post. Any reader can subscribe.
- WebSub and rssCloud work in both directions. As a subscriber, RSS Expert discovers a feed's hub or cloud and receives posts as soon as they're published. As a publisher, it is its own hub and its own cloud, with no third-party service in between.
- Webmention tells the other side about a reply, and Micropub lets another application publish through it.
On the fediverse side, enabled with RSS_EXPERT_ACTIVITYPUB:
@yourhandle@rss.expertbecomes an address anyone on Mastodon can find and follow. When you publish, the post appears in their timeline.- Conversation crosses in both directions. A reply written on Mastodon joins the thread here, and a reply written here reaches the remote author's inbox.
- Editing sends an Update. Removing a post sends a Delete. Likes and boosts are counted. HTTP signatures support both the newer standard, RFC 9421, and the older draft Mastodon still uses. The system remembers which one each server accepts.
What it's for, and who it's for
It's for someone who wants to read the open web in one place, publish without depending on a platform, and talk to people on other networks while keeping their identity, history, and provenance on their own side.
A blog that is also a reader and a fediverse account, without becoming three different services.
It isn't for everyone. If you only want to post something and be seen by a lot of people quickly, a large network will serve you better. RSS Expert trades reach for ownership. Fewer people will find you for free, but what's yours stays yours, and nobody in the middle decides what happens to it.
Why it's built this way
Every major choice has a recorded reason in docs/decisions/, in the ADRs. These are the big ones:
- Small on purpose. A static binary without cgo, a
FROM scratchimage, and SQLite instead of a database server. It can run on almost nothing, and there are fewer things waiting to break. - No outside library for the sensitive parts. ActivityPub HTTP signatures were written by hand and tested against known vectors instead of inheriting an abandoned dependency. TOTP follows the same discipline.
- Security defaults to the safe choice. Every outbound request passes through an SSRF guard, checked after DNS resolution and before connecting, on every hop. Upload types come from their bytes, files are decoded before storage, and metadata is stripped. When a setting is a security decision, its default is the safe one.
- It can't look AI-made. The code reads like a person wrote it. The visual design follows real reference pages, with no purple gradient, glassmorphism, or emoji in the interface. Every color and size comes from one token file.
Where the ideas came from
The implementation is independent. No code was copied from another project.
But the interoperability knowledge that makes it possible came from other people's work: RSS, OPML, rssCloud, and Dave Winer's Textcasting; Ricardo Mendes's RSC, which proved the idea could work and gave this project a map; Micropub, Webmention, and the IndieWeb microformats; and ActivityPub and ActivityStreams from the W3C.
Where it is
rss.expert, version 0.0.1, in testing.
The federation loop has been proven between two instances I control and by a large test suite. One check remains, and no automated test can cover it: a real mastodon.social account following @pablo@rss.expert, with the conversation actually crossing both ways.
Until that happens, "it works" describes the code.
It doesn't yet describe the world outside.
Member discussion