Yesterday, recovering from a nasty (thankfully non-Covid) cold, I decided to build an import tool for pulling articles I've read & enjoyed in Omnivore into this blog as bookmarks (in the IndieWeb style).

Check out an example here with my bookmark of The Tyrany of Obviousness by P.E. Moskowitz.

I promise I won't gush about Omnivore too much, but there's a good reason I put the effort into building a custom integration here. Omnivore is brilliant. It's been the first read-it-later app I've found simple & powerful enough to actually read from. The text-to-speech systems they have are outstanding (use "Fable" if you like an English/SSB accent!), being able to subscribe to RSS feeds, email newsletters, and pull (even some paywalled) browser articles in make it useful everywhere, and their dedication to open source and commitment to sustainable growth make me love this tool even more.

So my import tool had a lot to live up to! I decided to start with a proof-of-concept Go importer (it's available in this blog's repo under an MIT licence). It works surprisingly well! It seeks out articles that have been completely read and have at least 1 annotation (as a signal for "I like it enough to share it"), then pulls my commentary, highlights, and the title/author/summary into the markdown frontmatter & content so I can display my bookmark.


I built this as a sick-day hack so I could figure out if it was worthwhile making something more permanent, so it definitely has its limitations!

  • I have to manually run a task import to pull any new articles into my blog. (I may automate this, but the What's Next section, below, has a better idea)
  • It re-processes every article every time it runs. Large lists will likely be slow.
  • A limitation of Omnivore's API means that the readAt timestamp (which I use as the publish timestamp for my bookmark) gets updated every time you read that article.
    • The Omnivore team have very kindly said they'll consider putting a firstRead column in the response for usecases like this! It's been absolutely delightful to have a human response from their team, and even moreso to have something like this considered, even if it never makes it to the top of the backlog. (Thanks Jackson!)
  • I haven't yet tested if this will work articles that get pulled into Omnivore by email (another frankly awesome feature) but there's only one way to find out!

What's next

I'm already enjoying this tool a bunch, so I think I'll develop it further. If others are interested I'll try to make it something easy to run as well (do get in touch on mastodon or send an email if that sounds interesting!)

My thoughts are to turn this into a service/serverless function that will listen for Omnivore's excellent webhooks, (configurably) filter down to events that should result in "publish a new bookmark", and trigger the Micropub endpoint of your blog with all the same highlight/annotation information.

This should mean that you could publish your favourite Omnivore articles to your blog no matter what it looks like or where it lives! Lots of blogging tools already support Micropub ( is a fave of mine), and tools like IndieKit (which is great, I use it here) can integrate with almost any statically generated blog too. This feels like a great way to make it available for all!

Long live the cosy web, filled with stories and articles recommended by friends and humans, not corporations and algorithms!