Table of Contents

RSS and Atom by Hand

Feeds are just XML files on your site. Tools generate them, but hand-writing one is 20 lines and teaches you the format.

Minimal Atom Feed

feed.xml:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>~you's log</title>
  <link href="https://tilde.town/~you/blog/"/>
  <link rel="self" href="https://tilde.town/~you/blog/feed.xml"/>
  <updated>2026-10-05T12:00:00Z</updated>
  <id>https://tilde.town/~you/blog/</id>
 
  <entry>
    <title>Post title</title>
    <link href="https://tilde.town/~you/blog/post-title.html"/>
    <id>https://tilde.town/~you/blog/post-title.html</id>
    <updated>2026-10-05T12:00:00Z</updated>
    <summary>First line or summary.</summary>
  </entry>
</feed>

Rules that matter: <id> must be unique and stable (the post URL works), <updated> in RFC3339/ISO8601 with timezone, newest entries first. Fifteen entries is plenty.

Minimal RSS 2.0

rss.xml:

<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>~you's log</title>
  <link>https://tilde.town/~you/blog/</link>
  <description>notes</description>
  <item>
    <title>Post title</title>
    <link>https://tilde.town/~you/blog/post-title.html</link>
    <guid>https://tilde.town/~you/blog/post-title.html</guid>
    <pubDate>Sun, 05 Oct 2026 12:00:00 +0000</pubDate>
    <description>First line or summary.</description>
  </item>
</channel>
</rss>

RSS dates are RFC822 format; Atom uses ISO8601. Atom is the simpler format, and every reader reads it.

In <head>, which is what readers and browsers autodiscover:

<link rel="alternate" type="application/atom+xml" title="~you's log" href="feed.xml">

Generating It

When hand-editing gets old, posts as title|date|url lines become entries:

{
  printf '<?xml version="1.0" encoding="utf-8"?>\n<feed xmlns="http://www.w3.org/2005/Atom">\n'
  printf '<title>site</title><id>%s</id><updated>%s</updated>\n' \
    "$base" "$(date -u +%FT%TZ)"
  while IFS='|' read -r title url when; do
    printf '<entry><title>%s</title><link href="%s"/><id>%s</id><updated>%s</updated></entry>\n' \
      "$title" "$url" "$url" "$when"
  done < posts.txt
  printf '</feed>\n'
} > feed.xml

bashblog, saait, and ssg all generate feeds for you. See Minimal Static Site Generators.

Validate

xmllint --noout feed.xml                            # well-formed XML (libxml2-utils)
curl -sI https://host/~you/feed.xml | head -1       # served? (200 + type)

Readers

twtxt

The bare-bones alternative: a twtxt.txt, one ISO8601<TAB>text per line, posted in your public dir. saait emits one; some tildes crawl them. See twtxt.

See Also