Narrating your blog with Kokoro, a local and opensource text-to-speech model

Listen to this article instead ▶ 0:00 / 0:00 0.75× 1× 1.25× 1.5× 2× Your browser does not support the audio element Seven years ago I used Google’s text-to-speech API to create audio versions of my posts. There was a Python script that parsed the Markdown file, cleaned it up, chunked it to stay under Google’s 5000 byte limit, convert each chunk to an MP3, stitch them together, and finally embed the resulting file with a Hugo shortcode that is essentiall a fancy <audio> tag. It worked, it was free1, and I was pretty pleased with it. The little audio player has been sitting at the top of my posts ever since. ...

July 12, 2026 · 6 min · Bart de Goede

Client-side semantic search for your static site

Listen to this article instead ▶ 0:00 / 0:00 0.75× 1× 1.25× 1.5× 2× Your browser does not support the audio element Eight years ago I added client-side search to this blog with Lunr.js. It creates an inverted index at build time, ships it as JSON, and matches strings in your browser. No server-side engine required. It has worked fine ever since, in the sense that it finds a post if you type a word that is actually in it. ...

July 10, 2026 · 15 min · Bart de Goede

Building a semantic search engine in ±250 lines of Python

Listen to this article instead ▶ 0:00 / 0:00 0.75× 1× 1.25× 1.5× 2× Your browser does not support the audio element Once upon a time I wrote a post about building a toy TF-IDF keyword search engine. It has been one of the more popular posts I’ve written, and in this age of AI I felt a sequel has been long overdue. It’s pretty fast (even though it’s written in pure Python), it ranks results with TF-IDF, and it can rank 6.4 million Wikipedia articles for a given query in milliseconds. But it has absolutely no context of what words mean. ...

February 9, 2026 · 14 min · Bart de Goede