Building my own custom standalone comments app

Surely, one day, eventually, I will write a blog post that isn’t about vibecoding some bauble into existence and actually get back to something deeper. I think learning how vibecoding (and coaxing some form of LLM to do stuff in general) is an important thing to understand, not just read about. I’m absolutely not an AI Evangelist, but this work has changed my perception of LLMs and agentic tools as they (rapidly, so rapidly) increase in capacity. This is not that day.

This website is published using the outstanding Hugo static site generator. Content is managed on my laptop as markdown files in folders. Files. In folders. Like regular documents. Without databases or Gutenberg editors etc. I edit the markdown files in Obsidian, and then publish the website - as static HTML files - to my server. The server doesn’t have a database, nor a content management system. It’s just dumb files - the oldest, most reliable, safest, least-resource-intensive way of hosting content on the internet.

Which means that when I want to add functionality like search, I need to add that somehow. Or if I want people to be able to leave comments. Both are trivial using something like WordPress on the server, but that’s way more overkill than I need.

So, I built a custom search tool that integrates with Hugo. And now I’ve built a custom comment management platform that integrates with Hugo. Both are bare-minimum-viable-product solutions, with just PHP and a file-based database using SQLite. No MySQL/MariaDB/whatever. No NodeJS. No Hibbidy Jibbity Sparkle Framework or whatever the kids are building with these days. Just files.

When I say I built, I mean Claude built them. Vibecoded. I didn’t touch a line of code for either. I fired up Terminal on my Mac, launched Claude Code, and prompted my way to working applications that are now deployed in “production” on this website. Both are available on GitHub12 if anyone wants to try using them - but know that they were built as minimum-viable-products for my specific use-case, and are not generalized Platforms. They don’t handle multiple websites. They run as simple folders of files that are deployed on my own website.

The vibecoding didn’t happen in 1 shot. It took 40 conversational turns over 14 hours (with 8 of those hours spent vibesleeping). It started with a simple prompt:

I have a static website generated by Hugo. It’s just plain HTML files but the server can also run PHP and SQLite. I want to build a standalone system to manage comments for content published to the website. It needs to be embeddable on each web page (using a Hugo shortcode) and comments need to be associated with the URL of the content. Comments should be threaded, with commenters leaving their name and email address and URL to their own website. The tool needs to be able to import comments in Disqus export format. I’m currently using TalkYard.io and want to migrate comments to this standalone comment manager when it’s working.

(lots and lots of back-and-forth. 39 more conversational turns, to be clear. A lot of back-and-forth with a bot that was simultaneously amazing and mind-numbingly frustrating)

I would point out things like “It doesn’t seem to work anymore. Please fix it.” and it would respond “OMG! You’re totally RIGHT! Why didn’t I think of that!” and eventually fix it.

The mind-numbingly frustrating part was that it would keep creating fresh comments.db database files, which, when rsynced to the server, overwrote the production comments.db file (which, thankfully, I have a backup for).

👤 USER: it seems to load now. Golly, i’d like to avoid catastrophic data loss in the future. Please don’t nuke databases or tables. And having an empty comments.db file that could overwrite the production comments.db file on the server when I upload the files is risky. Maybe start with an empty comments-default.db and populate comments.db?

🤖 CLAUDE: You’re absolutely right - that was a close call! Let me implement a safer database handling system…

(it was not, in fact, a close call - the production database had already been overwritten at this point. Claude did some stuff and after some more prompting actually came up with what seems to be a better way to handle the database files, and provided a backup tool)

I wanted a comment admin interface and the ability for commenters to subscribe to responses:

Screenshot of the Comments admin UI, showing the list of comments, and moderation tools.

Comments admin UI

Screenshot of the Comments admin UI, showing the list of comments, and moderation tools.

Image by D'Arcy Norman

I wondered about security holes - am I vibecoding a big gaping security vulnerability on the server? So I tasked it with doing a security audit. It claims it’s plugged the major risks and gives the code an A- for security. Which is what a scheming bot would say, but whatever.

I wanted a way to display “Recent Comments” on my blog, and it delivered a Hugo shortcode that I could embed on any page, that used the Comments API to pull the last several comments:

Screenshot of the Recent Comments page on my website, listing the last 20 comments posted across all content.

Recent Comments page on my website

Screenshot of the Recent Comments page on my website, listing the last 20 comments posted across all content.

Image by D'Arcy Norman

It’s now to the point that the Claude Code generated application is currently powering comments on this blog. It imported all of the previous comments (which went from Disqus to TalkYard to, now, this).

Why would I do this? It breaks the “Hugo publishes static files and these aren’t technically static files anymore!” ethos - but so did TalkYard and Disqus. But at least these are a) very (VERY) simple applications in terms of server resources needed and b) they are completely self-contained on this server, with no external dependencies or data sharing.

Anyway. It seems to work for me, and I’ll keep using it for now. It might be useful for others to play with. Who knows?

Last updated: October 8, 2025