Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

I built a tiny RSS generator for my Advent of Code solutions

RSS/Atom feeds are one of the great technologies in the open web. They allow me to follow other people and them to follow me.

This week, I started solving Advent of Code problems and this time I’m publishing my explanations as part of my Digital Garden and that doesn’t support separated RSS feeds for a subset of notes.

Two IndieWeb principles that I love are Make what you need and Use what you make. In that spirit, I built a tiny tool today afterwork to enable people to follow my Advent of Code explanations via RSS.

A bit of background: my personal website at https://hamatti.org is built with Eleventy (and a bunch of custom scripts) and my digital garden at https://notes.hamatti.org is powered by notes in Obsidian and Quartz that turns them to a website.

To build this tiny RSS generator, I combined a Node.js script with Eleventy’s Global Data Files and templating.

const fs = require("fs");

function addEntry(entryUrl) {
  // Read existing JSON in
  const data = JSON.parse(fs.readFileSync("_data/aoc2025.json", "utf-8"));

  // Extract Advent of Code puzzle day from URL
  // URL looks like this:
  // https://notes.hamatti.org/technology/advent-of-code/2025/day-1
  // so capture the number from `day-1` part.
  const day = entryUrl.match(/day-(\d+)/)[1];

  const today = new Date();

  // Add new feed entry
  data.entries.push({
    url: entryUrl,
    title: `Advent of Code 2025, day ${day}, explanation and solution.`,
    created: today,
  });

  // Update metadata
  data.updated = today;

  // Write new data to JSON file
  fs.writeFileSync("_data/aoc2025.json", JSON.stringify(data));
}

if (process.argv.length < 3) {
  console.log("Usage: npm run aocfeed [url-to-note]");
  process.exit(1);
}

addEntry(process.argv[2]);

It’s a tiny script that reads existing JSON, adds a new entry and writes it back.

Unfortunately I don’t yet have an easy way to add the full content since it’s not tied to my digital garden publishing pipeline but that can be an exercise for a day when I have more time.

The data it writes looks like this, at _data/aoc2025.json :

{
  "entries": [
    {
      "url": "https://notes.hamatti.org/technology/advent-of-code/2025/day-1",
      "title": "Advent of Code 2025, day 1, explanation and solution.",
      "created": "2025-12-02T15:17:43.981Z"
    },
    {
      "url": "https://notes.hamatti.org/technology/advent-of-code/2025/day-2",
      "title": "Advent of Code 2025, day 2, explanation and solution.",
      "created": "2025-12-02T15:17:58.315Z"
    }
  ],
  "updated": "2025-12-02T15:17:58.315Z"
}

and I have a feed template like this

---
permalink: feed/aoc2025.xml
excludeFromSitemap: true
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Advent of Code 2025 - Solutions and explanations by Juhis</title>
  <link href="https://hamatti.org/feed/aoc2025.xml" rel="self" />
  <link href="https://notes.hamatti.org/technology/advent-of-code/2025/advent-of-code-2025-landing-page" />
  <updated>{{aoc2025.updated}}</updated>
  <id>https://hamatti.org/feed/aoc2025.xml</id>
  <author>
    <name>{{ metadata.author.name }}</name>
    <email>{{ metadata.author.email }}</email>
  </author>
  {%- for entry in aoc2025.entries | reverse | limit(30) %}
  <entry>
    <title>{{entry.title}}</title>
    <link href="{{ entry.url }}" />
    <updated>{{ entry.created }}</updated>
    <id>{{entry.url}}</id>
    <content type="html">
      {{entry.title}}
    </content>
  </entry>
  {%- endfor %}
</feed>

Which reads data from the aoc2025.json file and populates a feed whenever I call Eleventy to create a new build.

Once I’ve published a new note, I run

node _scripts/updateAdventOfCodeFeed.js [url-to-note]

and push changes to my website.

Once that deploy is done, users can follow my Advent of Code via https://hamatti.org/feed/aoc2025.xml.


If something above resonated with you, let's start a discussion about it! Email me at juhamattisantala at gmail dot com and share your thoughts. In 2025, I want to have more deeper discussions with people from around the world and I'd love if you'd be part of that.