Creates an RSS feed from a page that does not offer one, by watching the page and turning repeated elements into feed entries.
Build me a feed maker that replaces RSS.app: an RSS feed from a page that does not offer one, that keeps working when the site changes. STACK - Node 20+ with Fastify - SQLite through better-sqlite3, WAL mode - A plain HTTP fetch first; a headless browser only for pages that genuinely need one - Caddy in front THE DATA MODEL - feeds: id, slug, source_url, title, description, mode, selectors_json, render_js, fetch_interval_seconds, next_fetch_at, etag, last_modified, last_fetched_at, consecutive_failures, last_error, is_active - items: id, feed_id, guid, url, title, author, summary_html, content_html, image_path, published_at, first_seen_at, content_hash - snapshots: id, feed_id, html_gzip, fetched_at — the source document, kept for the last few fetches so a broken selector can be diagnosed against what actually arrived - checks: id, feed_id, status, item_count, new_count, changed, at — every fetch, whether or not anything changed - subscribers: id, feed_id, kind, target — for the ones you want pushed rather than polled FINDING THE ITEMS - First, look for a feed the site already has: a link tag, the common paths, a JSON endpoint the page itself calls. A large share of "sites with no feed" have one, and using it is free and stable - Then structured data: JSON-LD, microdata, an OpenGraph list. More stable than CSS selectors - Then selectors: a repeating container, and within it the title, link, date, summary and image - Auto-detection as a starting point — find the repeated element with the most consistent structure — then let a human confirm and adjust with a live preview of the extracted items - Store several fallback selectors per field, tried in order. A single brittle selector is what makes these feeds break STABLE IDENTITY, WHICH DECIDES WHETHER THE FEED IS USABLE - The guid is the item's canonical URL, with tracking parameters stripped - If there is no link, hash the title and the date. Never use the position on the page — a reordered list would republish everything - An item whose content changed keeps its guid and is marked updated, not republished - Never emit an item that has been emitted before, even after a full re-fetch or a restart. Keeping that promise is the whole difference between a feed and a nuisance - A sudden change where every guid is new is a broken selector, not fifty new articles. Detect it, refuse to publish, and alert FETCHING POLITELY - Conditional requests with ETag and If-Modified-Since, always - Honour robots.txt and Retry-After, use an identifiable user agent with a URL explaining what it is, and rate-limit per host - Adaptive interval learned from how often the page actually changes — checking a weekly blog every ten minutes is rude and pointless - Back off exponentially on failure and disable after enough consecutive ones, with a clear message - The headless browser only when the plain fetch finds nothing, because it is fifty times the cost. Record which mode each feed uses, and try the cheap one again periodically WHEN THE SITE CHANGES, WHICH IT WILL - This is the recurring cost of the product, and the tool should make it a five-minute fix rather than an investigation - Keep the last snapshots, so a broken feed can be diagnosed against the HTML that actually arrived - Alert when a feed returns zero items after previously returning some, or when the count changes by an implausible amount - A repair screen: the stored HTML on one side, the selectors on the other, with a live preview - A health list of every feed with its last successful extraction, which is the page the owner should look at weekly THE OUTPUT - Valid RSS 2.0, Atom and JSON Feed, all three, with correct dates and escaping — validate against a real validator in the test suite - Full content where the page allows it, a summary otherwise - Images fetched, stored locally and referenced, so the feed does not hotlink and does not break when the source reorganises - Correct caching headers and conditional responses, because feed readers poll and you should be a good citizen in both directions - Optional filters per feed: include or exclude by keyword, minimum length, or a required field LEGAL AND POLITE - Respect robots.txt and terms. Republishing somebody's full content as your own feed is a different thing from reading it yourself - A feed for personal reading is fine; a public feed of somebody else's writing is theirs, not yours. Say this in the README and default new feeds to private with a token OPERATIONS - .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, USER_AGENT_URL, SESSION_SECRET, RENDER_TIMEOUT_MS - Migrations on boot, each once - Snapshots pruned on a schedule - Nightly backup off the machine, restore script - Health endpoint reporting the oldest overdue feed and the failure count WHAT MATTERS MOST Stable guids and the broken-selector alarm. Build identity and the never-republish rule first, then run twenty real feeds for a fortnight. A feed that occasionally re-sends fifty old items is a feed that gets unsubscribed the first time it happens. Give me the repository, the fetcher, the selector editor, migrations, .env.example, and a README with deploy steps behind Caddy.
What you lose
- Selectors that keep working when a site changes its markup, which is the recurring cost
- Rendering pages that need JavaScript before extracting
- Hosted feed URLs with caching
If you would rather not build
- A scraper writing a static XML file
What it costs
read from their page 15 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $9.99/mo | — | 15 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
RSS-Bridge
$0Generates feeds for sites that do not offer them, with many bridges built in.
RSS-Bridge/rss-bridgefree · open source
changedetection.io
$0Watches pages and can publish changes as a feed.
dgtlmoon/changedetection.iofree · open source
Why this verdict
our own opinion · changed only by a person
87/100
Verdict yes at 87. Selectors plus a hash for the GUID. Alerting on an empty extraction is what stops a silently broken feed.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about RSS.app
answered from the record above
Is RSS.app free?
No — the plan we track is $9.99 a month. Basic at around $9.99/month billed monthly for a number of generated feeds.
Can you replace RSS.app by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 87 out of 100, build time one session. Read what you lose before you decide.
How much does RSS.app cost?
$9.99 a month on Basic — $119.88 a year. Recorded 10 Aug 2026.
What do you lose by replacing RSS.app?
Selectors that keep working when a site changes its markup, which is the recurring cost; Rendering pages that need JavaScript before extracting; Hosted feed URLs with caching. If any of those carry weight for you, keep paying.
Is there an open-source alternative to RSS.app?
Yes: RSS-Bridge, changedetection.io. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

