Inbound and outbound RSS
Most of the talk about RSS is about publishing. A feed is something your site emits: you write a post, and the feed is the machine-readable copy that goes out the door. Almost every blog does this. It is the easy half, and it has been solved for twenty years.
The harder, rarer half is the other direction — not emitting feeds, but reading them. Treating other people’s feeds as the way you follow them, inside your own site, as a first-class thing rather than an export nobody looks at. Dave Winer has been asking who else builds this. Manton Reece replied that he isn’t aware of any social platform doing inbound RSS except Micro.blog.
My site does both. The wiring is open source, so here is exactly how.
Outbound
The feeds are generated by the Eleventy theme and served straight off the site:
- RSS 2.0 — https://rmendes.net/feed.xml
- JSON Feed 1.1 — https://rmendes.net/feed.json
It is RSS 2.0, not Atom: <rss version="2.0">, a <channel>, <item> elements, RFC-822 dates. The kind of feed Dave’s tools have always read. That is the whole outbound story, and as I said, it is the easy half.
Inbound
This is the interesting part. The site runs on Indiekit — the open-source IndieWeb server created by Paul Robert Lloyd — plus a set of plugins I maintain, several of which exist only to bring feeds in:
- A Microsub social reader: subscriptions sorted into channels, read in a timeline inside the site. This is the closest thing to the Micro.blog model — you follow a feed, and you read it here, not somewhere else. It reads RSS, Atom, JSON Feed, and h-feed, the IndieWeb’s own microformats feed, and it uses WebSub to pick up new posts close to the moment they’re published.
- An RSS reader that aggregates feeds — RSS, Atom, and JSON Feed — including over the Google Reader API my own FreshRSS server speaks.
- A blogroll that pulls feeds in from several sources at once and re-syncs every hour.
- A podroll for podcast subscriptions, which are themselves just RSS, fed from that same FreshRSS instance.
Between them, the readers take in the whole spectrum of open feed formats: RSS 2.0, Atom, JSON Feed, and h-feed. None of this is decoration. The site is as much a place to read as a place to write, which is the part most “social” software quietly dropped when following someone became a row in a private database instead of a subscription to an open feed.
OPML, in both directions
The blogroll is where the two halves meet. Right now it is tracking 389 blogs and 1,707 items, and it builds that list from four sources at once: an uploaded OPML file, a remote OPML URL, my own Microsub subscriptions, and FeedLand self-hosted account. Feeds arrive as OPML and leave as OPML.
The FeedLand part is worth spelling out, because it is FeedLand all the way down. I run my own instance — I packaged FeedLand for self-hosting two ways, as a Cloudron app and as a hardened Docker Compose stack — and it lives at feedland.rmendes.net. Its OPML is a live source feeding the blogroll, which renders on this site. So the loop closes entirely on my own infrastructure: my FeedLand, my blogroll, my frontend, joined by OPML and re-synced every hour.
And the list leaves as OPML here, in public:
That is the whole reading list — about 385 feeds — as a clean OPML 2.0 file, the kind any reader or aggregator can import. The Microsub reader exports its own subscriptions the same way, though that one stays behind a login since it is a personal reading list.
OPML and FeedLand are both Dave’s work. Which means his formats aren’t something I’m planning to support someday — they’re already load-bearing here. FeedLand flows into the blogroll, the blogroll hands an OPML file back out, and the feeds themselves move in RSS 2.0 the entire way.
Credit where it’s due
Almost none of this is mine to claim, and it would be wrong to let the post imply otherwise. Indiekit is Paul Robert Lloyd’s work — he built and maintains the open-source server this entire site runs on. I write plugins that sit on top of it; the foundation is his, and it is a quietly remarkable piece of software.
The building blocks underneath go back further still, to the IndieWeb community. Microsub — the reader protocol that makes the social reader possible — was specified by Aaron Parecki, and I leaned hard on his reference implementations, Aperture and Monocle, along with Peter Stuifzand’s Go Microsub server Ekster, when I built my own plugin earlier this year. Microformats, the basis for h-feed, trace back to Tantek Çelik and a long roll of contributors on the IndieWeb wiki. And Microsub only makes sense paired with its publishing half, Micropub — another IndieWeb spec, and the one Indiekit (again, Paul’s work) implements so I can post here at all.
I should also be honest about how it got built. I had waited years for the right framework to commit to, (and tried A lot of different solutions over the last 2 decades) and the volume of plugin code behind these features is more than I could have written on my own in just a few months — Claude Code is how it actually got done. My part in all of this is orchestrating: wiring the pieces together and self-hosting them. Dave’s RSS and OPML are the oldest pipes in the same system. I have been using RSS as my main source of curated information since 2003 now !
The point
This is the old shape of the web: open formats, no accounts required to read each other, every site able to both publish and subscribe, and software you can run yourself instead of renting. None of it is novel. It is RSS 2.0 and OPML — the two formats this has always run on — wired up in both directions on a site one person runs.
If you’re building something on the same formats, point it at any of the URLs above and see what comes back. That is the whole idea — put up an app, and see who works with it.
AI: Text Co-drafted · Claude Code
Drafted by Claude Code from facts and direction supplied by me. Every technical claim was verified against the site's own source code and live endpoints before writing. Reviewed and edited by me.
Comments
Sign in with your website to comment:
Loading comments...
No comments yet. Be the first to share your thoughts!