Frust
Moving away from Feedly meant choosing a self-hosted replacement. Every option — Miniflux, FreshRSS, Tiny Tiny RSS — runs as a persistent web service: a port to expose, a database to back up, a daemon to restart after a kernel update. The filtering features I wanted were locked behind a paywall anyway. Frust started as a Feedly clone, then the obvious question surfaced: why run a service at all? An RSS aggregator just fetches URLs and produces files. Run it from cron, write static files, serve them with whatever HTTP server is already running. No port, no database, no daemon.
Features
Filtering — include or exclude articles by keyword, phrase, or regex; each rule scopes independently to title, summary, or full content
Grouping — aggregate multiple feeds into a single output file; useful for combining related sources or creating topic digests
Force full-text — when a feed only provides a summary, a CSS selector scrapes the full article body from the source page and injects it into the feed entry
Multiple export formats — output format is chosen by file extension:
Extension Format .rss/.xmlRSS 2.0 .atomAtom 1.0 .jsonJSON Feed 1.1 .mdMarkdown with YAML frontmatter .epubEPUB 3.0 (grouped feeds as a book) Feed enrichment — inject custom HTML at the top or bottom of articles (at feed, group, or global level) to add bookmark buttons, share links, or calls to external APIs like Shiori
OPML import/export — bootstrap a config from an existing OPML subscription list; export back to OPML for portability
ZIP export — bundle a feed, group, or the full output as a ZIP for offline transfer or archiving
Lightweight — written in Rust; pure-Rust dependencies (no OpenSSL, no zlib); statically linked MUSL binary runs on any Linux including ARM
Stateless — no database; run via cron, not as a background daemon
Privacy — no telemetry; runs as a non-root user; source on Codeberg
Use cases
Offline reading on an e-reader. Group a week of long-form blogs into a single EPUB and side-load it onto a Kindle or Kobo. No connection needed after the sync — read on a plane, in the garden, anywhere.
Clean up ad-heavy tech feeds. Publishers mix editorial content with sponsored posts. A keep: false filter on “sponsored”, “advertisement”, “partner” strips them from the output before your reader app ever sees them.
Recover full articles from truncated feeds. Some publishers deliberately cut off their feeds to force web visits. The selector option fetches the source page and injects the full article body into the feed entry — your reader gets the whole thing.
Home router or NAS. The ARM MUSL binary has no runtime dependencies — drop it on an always-on OpenWrt router, Raspberry Pi, or NAS. Set a cron job pointing at an output directory served by the device’s built-in HTTP server.
Bookmark manager integration. Use feed enrichment to inject a “Save to Shiori” button into every article, pre-filled with the article URL and title. One click from any feed reader client that renders HTML.
Comparison
Miniflux, FreshRSS, and Tiny Tiny RSS are full readers — they include a web UI, user accounts, and read-state tracking. feedpushr is a backend aggregator that pushes items to external endpoints. frust is closest to feedpushr in role (no reader UI), but writes static files instead of pushing to a live destination.
| frust | Miniflux | FreshRSS | feedpushr | |
|---|---|---|---|---|
| No persistent service (cron-only) | ✅ | ❌ | ❌ | ❌ |
| No database required | ✅ | ❌ PostgreSQL | ❌ MySQL/SQLite | ❌ BoltDB |
| Static file output | ✅ | ❌ | ❌ | ❌ |
| EPUB export | ✅ | ❌ | ❌ | ❌ |
| Regex/keyword filtering | ✅ | ✅ | ✅ | ✅ |
| Full-text extraction | ✅ CSS selector | ✅ | ✅ XPath | ✅ filter plugin |
| Push to webhooks / external APIs | ❌ | ❌ | ❌ | ✅ |
| Web UI / read-state tracking | ❌ | ✅ | ✅ | ✅ |
| ARM fully static binary | ✅ MUSL | Partial | ❌ | Partial (AMD64 plugins only) |
The absence of a web UI is intentional: frust writes standard feed files consumed by any client — Reeder, NetNewsWire, Fluent Reader, or a self-hosted Miniflux instance pointed at the static files.
Installation
cargo install frustCross-compile for ARM devices (routers, NAS, single-board computers):
rustup target add armv7-unknown-linux-musleabihf
cargo install cross
cross build --release --target armv7-unknown-linux-musleabihf
# static binary at target/armv7-unknown-linux-musleabihf/release/frustTypical cron entry (every 30 minutes):
*/30 * * * * /usr/local/bin/frust /etc/frust/config.yaml >> /var/log/frust.log 2>&1