Choosing a feed format: RSS 2.0, Atom and JSON Feed
The audience decides the format: readers and podcasts need RSS, Atom is stricter and date-safe, and JSON Feed is easiest for modern clients.
What each format is good at
| RSS 2.0 | Atom | JSON Feed | |
|---|---|---|---|
| Specification | Harvard/UserLand, loosely specified | RFC 4287, a formal standard | Community spec, two versions |
| Maturity | Universal reader support | Universal, but rarely chosen first | Modern readers and applications |
| Dates | RFC 822, easily malformed | RFC 3339, unambiguous, timezone required | RFC 3339 |
| Identifiers | guid, often omitted | id, required, must be a URI | id, required |
| Content | description only, plus content:encoded extension | Native rich content with type and language | Native content_html and content_text |
| Podcast support | Required by every podcast directory | Essentially unused in podcasting | Not supported |
| Escaping strictness | Very tolerant, hence very broken | Strict XML, so errors are caught | JSON, so no escaping of markup |
{
"version": "https://jsonfeed.org/version/1.1",
"title": "Release Notes",
"home_page_url": "https://example.com/releases",
"feed_url": "https://example.com/feed.json",
"language": "en-GB",
"authors": [{ "name": "Platform Team", "url": "https://example.com/team" }],
"items": [
{
"id": "https://example.com/releases/2026-09-platform-3-2",
"url": "https://example.com/releases/2026-09-platform-3-2",
"title": "Platform 3.2",
"content_html": "<p>Streaming transforms and faster cold start.</p>",
"date_published": "2026-09-18T09:00:00+01:00",
"tags": ["platform", "release"]
}
]
}- Podcasts must be RSS 2.0, because the directory ecosystem reads the Apple and Podcasting 2.0 namespaces and nothing else.
- Atom is the right choice if you want a strict parser to catch your own escaping mistakes at build time.
- JSON Feed is the easiest to generate from a modern application, because your template engine does the escaping.
- Publishing all three is cheap: one internal item model, three serialisers.
One item model, several serialisers
from dataclasses import dataclass
from datetime import datetime
@dataclass
class Item:
id: str # stable URI, never changes
title: str
url: str
summary: str # short, plain text
html: str # full content, trusted HTML
published: datetime # timezone aware
updated: datetime | None = None
author: str | None = None
tags: tuple[str, ...] = ()
# The model is the contract. Only the serialisation differs per format, which is
# what keeps three feeds from drifting apart.<!-- Atom benefit in practice: the date is unambiguous and required -->
<entry>
<id>https://example.com/releases/2026-09-platform-3-2</id>
<title>Platform 3.2</title>
<updated>2026-09-18T09:00:00+01:00</updated>
<author><name>Platform Team</name></author>
<link rel="alternate" href="https://example.com/releases/2026-09-platform-3-2"/>
<summary>Streaming transforms and faster cold start.</summary>
<content type="html"><p>Streaming transforms and faster cold start.</p></content>
</entry>💡
Whatever you choose, the item identifier must be stable for the life of the item. It is the only thing a reader uses to decide whether it has already shown the item, so changing it re-notifies every subscriber.
FAQ
Should I publish RSS and Atom from the same URL?
No. Serve each format from its own URL and declare both from the page head, so a reader can pick. Content negotiation on one URL with Vary: Accept also works but confuses feed validators.
Is JSON Feed worth publishing if my audience uses RSS readers?
Only if you also have applications that consume it. For a blog, RSS plus Atom covers everything; JSON Feed is for your own tooling and modern clients.
Related
The RSS 2.0 feed format Migrating between RSS, Atom and JSON Feed
Last refreshed 2026-09-18.