blogtato - 用 Git 同步的 Taskwarrior 风格 RSS 阅读器
RSS 阅读器有两种常见方向。一种是 Feedly、Inoreader 这类托管服务,优点是同步和移动端体验省心;另一种是 FreshRSS、Miniflux、Tiny Tiny RSS 这类自托管服务,优点是数据更可控,但需要维护一个长期运行的服务。
今天推荐的 kantord/blogtato 走的是第三条路:它是一个 Rust 写的 CLI RSS/Atom 阅读器,界面和查询方式受 Taskwarrior 启发,数据存成 JSONL 文件,并且可以用 Git 在多台机器之间同步。它不需要账号、不需要常驻服务器,也不要求你把阅读流搬进浏览器标签页。
发布时 GitHub 页面显示项目约 226 stars、4 forks,主要语言是 Rust,许可为 Apache-2.0。项目创建于 2026-02,最近仍在更新;最新 release 是 v0.1.25,发布时间为 2026-05-13。
项目概览
| 属性 | 详情 |
|---|---|
| 仓库 | kantord/blogtato |
| 定位 | CLI RSS/Atom feed reader |
| Stars | 约 226 |
| Forks | 4 |
| 主要语言 | Rust |
| 许可 | Apache-2.0 |
| Latest release | v0.1.25 |
它把 RSS 当成命令行待办列表来处理
blogtato 最有辨识度的地方,是它没有把 RSS 阅读器做成一个小型网页应用,而是把信息流处理成命令行对象。
安装后,你可以用 blog feed add 添加订阅,用 blog sync 拉取新内容,用 blog 查看默认列表。默认视图会显示最近三个月的未读文章,并按周分组;也可以切换为按日期、按周或按 feed 分组。
这种交互方式很像处理任务列表。你不是打开一个“内容中心”,而是在终端里筛选、打开、标记、导出一组条目。对每天已经在 shell 里工作的人来说,这比切到一个网页阅读器更轻。
查询语言是它的核心体验
README 里给出的示例能看出 blogtato 的设计重点:它不是只提供 list 和 read 两个命令,而是用简短的 query 组合 feed、已读状态、时间范围和分组方式。
例如,你可以按 feed shorthand 过滤,也可以用 .unread、.read、.all 切换状态;时间范围可以写成 1w.. 或 3m..1m;分组可以用 /d、/w、/f 控制。组合起来,就能表达“只看 Hacker News 最近未读,并按日期分组”这类日常需求。
这比传统 RSS 阅读器的文件夹树更像一个命令行过滤器。它适合已经习惯 rg、fd、jq、Taskwarrior 或 shell pipeline 的用户:你先缩小集合,再对结果执行打开、标记已读或导出。
Git 同步解决的是“少维护”
blogtato 的同步设计很有取舍。它的数据存储是 JSONL 文件;如果你希望多设备同步,可以把数据放进一个私有 Git 仓库,然后让 blog sync 在拉取 feed 的同时同步远端。
从性能角度看,README 也承认这不是最优雅的数据库方案。但它的目标不是把 RSS 阅读做成高性能后端,而是让 CLI 用户不用再维护一个服务。只要你已经有 GitHub、GitLab 或 Forgejo 这类远端仓库,就可以把订阅、文章状态和配置同步到其他机器。
更关键的是,项目强调 conflict-free merge。也就是说,即使两台机器上的阅读状态出现分叉,用户也不需要手动解 Git 冲突。Git 在这里更像一个同步传输层,而不是要求你把每次阅读都当成代码变更来管理。
离线和手动联网让它很安静
很多 RSS 工具会默认常驻、定时刷新、推送通知。blogtato 反过来:网络操作由用户触发,没有常驻服务器;不需要联网的操作可以离线完成。
这种设计适合“我想读的时候再读”的信息流管理。它不会自动把未读数推到你面前,也不会持续占用后台进程。你可以在一天中的某个固定时间运行 blog sync,筛选出值得看的内容,然后把其余内容保持在终端之外。
这也是它所谓 subscription detox 的实际含义。它不试图用更多推荐和通知抓住注意力,而是把 RSS 回到一个可查询、可标记、可导出的本地数据集。
OPML 导入降低迁移成本
一个新的 RSS 阅读器如果不能接住已有订阅,很难真正试用。blogtato 支持从 OPML 文件导入订阅,这意味着你可以从 Feedly、Inoreader、NetNewsWire、FreshRSS、Feeder、Tiny Tiny RSS、Outlook 等工具迁移 feed 列表。
这点让它适合渐进试用:先导入一份 OPML,在单机本地运行;如果觉得命令行工作流合适,再配置 Git 同步。README 也明确说 Git 同步是可选的,不配置远端时,blog sync 仍然可以正常拉取 feed。
换句话说,你不必一开始就承诺把整个阅读系统迁进去。先把它当作一个可离线、可脚本化的 RSS 终端客户端试一周,会更符合它的使用方式。
JSONL 导出适合二次处理
blogtato 支持把匹配 query 的文章导出为 JSONL。这个功能对普通阅读器用户可能不显眼,但对开发者很有用。
你可以把 .all export、某个 feed 的 export,或者某段时间范围的 export 接到其他工具里。比如做个人知识库导入、生成阅读报告、保存某类技术文章清单,或者用脚本统计哪些 feed 长期没有产出有用内容。
它没有把这些二次处理都内建成 UI 功能,而是把结构化数据交给外部工具。这个选择很 Unix:工具本身保持窄,把组合能力留给 shell、jq 和你自己的脚本。
ingest filter 是给挑剔用户的入口
README 里还有一个值得注意的配置:ingest_filter。它允许你配置一段 jq 表达式,在 blog sync 存储文章之前过滤或改写 post 对象。
典型用途包括过滤标题里的赞助内容、去掉链接里的跟踪参数,或者对 feed 数据做轻量清洗。这个设计没有引入任意 shell 脚本,而是选择 jq,原因很直接:feed 项目已经是结构化 JSON,用 jq 表达式更容易同步到其他机器,也更少依赖本机某个脚本路径。
这里也能看出 blogtato 的目标用户画像:它不是追求所有人都能点几下完成配置,而是服务于愿意用小工具整理输入流的人。
适合什么人先试
我会优先把 blogtato 推荐给这几类用户:
- 日常主要在终端工作,希望 RSS 也能进入命令行流程。
- 不想维护 FreshRSS / Miniflux 这类服务,但又希望多设备同步阅读状态。
- 喜欢 Taskwarrior 式的简短 query,而不是依赖文件夹和按钮。
- 想把订阅内容导出成 JSONL,再接入自己的脚本或知识库。
- 接受早期工具的边界,愿意用 Cargo 安装并自己管理本地数据目录。
如果你需要成熟移动端、全文抓取、网页端阅读体验、多人共享、复杂规则引擎或商业服务级同步,blogtato 不是替代品。它更像一个窄而安静的个人工具:把 RSS 变成本地可查询数据,再用 Git 做足够简单的同步。
小结
kantord/blogtato 的价值不在于重新发明 RSS,而在于把 RSS 放回开发者熟悉的工具链里。订阅是 feed,文章是可筛选条目,状态是本地数据,同步交给 Git,导出交给 JSONL。
如果你已经厌倦了阅读器里的通知、未读焦虑和又一个账号系统,但仍然想保留 RSS 的开放性,blogtato 值得试试。它可能不会成为所有人的主力阅读器,但很适合那些希望信息流更安静、更可脚本化的终端用户。