この記事ははてなエンジニア Advent Calendar 2025 の1月9日の記事です。
最近自分専用の RSS リーダーを楽しく自作しています。

まだまだ作り途中ではありますが。
この RSS リーダーは沢山の記事をぼーっと眺める用に作っています。タイムラインは一つのみでお互いに関係ない記事が時系列順にバーっとならんでいます。政治ニュースの次には美味しい情報、IT, アニメの情報、ちょっとセクシーな記事だったり匿名ダイアリーの意味のわからない記事だったりバラバラです。眺めているだけでこれがこれこそがインターネットだということを楽しめるわけでございます。

このRSSリーダーは沢山のフィードを登録すればするほど楽しくなります。ジャンルがバラバラな記事が並べば並ぶほど完成されていくわけです。高度なレコメンド順などはありません。アルゴリズムから解放されます。
またはてなブックマークのブクマ数も表示されます。これは嬉しい。

RSS はニュースやブログだけではなく、Google ニュースのキーワード検索や Mastodon, Bluesky, YouTube などでも提供されているので、色々と購読できるわけです。


RSS が提供されているないサイトでも大チェッカーを使うとサイトの更新を RSS にしてくれたりもします。
実装は Go のバックエンドと Vite + React の SPA の構成です。趣味の実装では自分でぴこぴこ楽しくプログラミングがしたいので依存ライブラリは少ないです。今のところバックエンドが依存しているサードパーティは mattn/go-sqlite3 だけで、 フロントエンドもReact と React Router と SWR と valibot くらい。 (依存の依存は除く)
インフラ構成としては DB に SQLite を使い、さくらインターネットの安いタイプのVPSにデプロイするというシンプルなものです。完全に自分専用です。いまのところ自分だけがアクセスできるように認証をかけています。
いろんなサイトが自由気ままに RSS フィードを書き出すのでパースするのは大変です。 例えば RSS に含まれる記事の公開時刻をパースするために次のように複数のフォーマットを試しています。
func ParseRSSDate(s string) (time.Time, error) { layouts := []string{ time.RFC1123Z, time.RFC1123, "Mon, 2 Jan 2006 15:04:05 -0700", "Mon, 2 Jan 2006 15:04:05 MST", "Mon, 02 Jan 2006 15:04 -0700", "Mon, 02 Jan 2006 15:04 MST", time.RFC822Z, time.RFC822, "02 Jan 2006 15:04 -0700", "02 Jan 2006 15:04 MST", time.RFC3339, } for _, layout := range layouts { t, e := time.Parse(layout, s) if e == nil { return t, nil } } return time.Time{}, fmt.Errorf("rss: cannot parse time: %s", s) }
すでに公開されている RSS パースライブラリを使えば楽できるんですけどね。完全に趣味の世界です。
将来的には
なんかができるといいかなぁ。
RSS リーダーを自作するのは楽しいです。単に有用ですし、ユーザーがひとりしかいないのに無限に記事が更新されていくので、寂しいこともないです。やろうと思えばいろいろ拡張する余地もあります。