With the release of Anthropic’s Fable, I thought it was a good chance to audit some of my projects and check out its capabilities. Running a full site audit with Claude Code surfaced an issue I had not known about - nobody could comment on this site.

The widget at the bottom of every post - giscus, which stores comments as GitHub Discussions - had been silently broken for a long time: it was pointed at a private repository, and giscus needs a public one. Every visitor who’d scrolled to the comment box had been looking at an error I never saw.

The obvious fix was to swap vendors, so we did. Cusdis looked ideal - open-source, privacy-friendly, free - but its hosted service turned out to be abandoned. The widget needed surgery just to render, and notifications simply never fired: the “no email notifications” issue had been open on GitHub for over six months, affecting paying customers too. No blame to the author - it was free software, generously given. But depending on an unmaintained hosted service is a slow-motion outage. I’d traded one dead dependency for another.

The Decision

That left the classic three options:

  • Pay someone. Hyvor Talk is the good privacy-first option, at about £12/month - £144 a year for a text box on a blog that gets a handful of comments.
  • Self-host. Run Cusdis myself - but its Docker image is pinned to a Node version that went end-of-life in 2023, so self-hosting doesn’t fix abandonment; it just transfers the patching burden to you. Maintained alternatives exist, like Remark42 and Comentario, but any of them means running a server for a text box.
  • Build. My site runs on Azure Static Web Apps, which includes managed Azure Functions on the free tier. Add a Table Storage account (pennies) and everything a comment system needs is already paid for.

A year ago, “build your own comment system” meant a weekend project that becomes a month of edge cases. As we have seen in the past on this blog - whether refactoring years of Emacs configuration in seven minutes or building a whole news aggregator - that maths changes with agentic coding.

This became an exercise in understanding the problem and getting to the value fast.

What an Afternoon Buys

The result is around 200 lines of API plus a form: anonymous commenting backed by Table Storage, pre-moderation so nothing appears until I approve it, a moderation page behind GitHub login, and push notifications to my phone via ntfy - the feature whose absence started all this.

One detail captures why building was different in kind, not just cost. Back when the third-party widget was still in the picture, I’d asked:

Me: can we add some kind of honey pot too?

The answer then was no - a honeypot only works if the server checks it, and the server belonged to someone else. The moment the API was mine, it became ten lines: a hidden field humans never see, and a server that silently bins anything that fills it in while telling the bot it succeeded. Owning the backend didn’t just fix a feature. It changed what features were possible.

The Honest ROI

The build wasn’t free, and pretending otherwise would spoil the argument.

The costs. My Fable 5 usage for the whole exercise - audit, forensics on the dead service, build, debugging - metered at roughly $60. At API rates that would be about a year of the comment-service subscription; in practice it was covered by the Claude subscription I already pay for, so the marginal cost was zero. There’s a symmetry worth noticing: the build ran on AI capacity I’d already bought, and the result runs on cloud capacity I’d already bought. The Azure side rounds to zero too - my entire 2026 spend to date is 93 pence, and the comment system’s only meter is Table Storage at about 4p per million reads.

The benefits. A one-off cost instead of a recurring one. Capabilities no vendor could sell me: the honeypot, notifications that actually work, and a privacy policy that got shorter - no third party, no email collected, no IP stored. Zero vendor risk: nobody can abandon, acquire, or enshittify my comment box except me. And transferable knowledge - I now know exactly what SWA managed functions can and can’t do, which makes the next build cheaper.

The cons, stated plainly. The code doesn’t stay finished. During the build, tooling was already nagging that my Node runtime needs upgrading. Runtimes age, SDKs move, npm audit finds things - each is a short Claude Code session inside the same subscription, but it’s an obligation, not an option. You also inherit the debugging: we lost a deploy cycle to an undocumented platform quirk (Azure Functions silently refuses to register any route starting with admin - now you know). And the whole case rests on scope: 200 lines I fully understand is ownable; rebuild five services and you’ve hired yourself as a platform team.

A subscription converts maintenance into a fee. Building converts the fee into a responsibility. The ROI holds only if you accept the responsibility - and skip it for long enough, and you’ve recreated exactly what you left: an unmaintained comment system, except now the negligent vendor is you.

What Else Could Be Fixed Like This?

My comment system died because it sat on someone else’s neglected infrastructure. The fix wasn’t a better vendor - it was noticing that the build-vs-buy calculus has quietly inverted for a whole class of software: small, well-understood scope; personal or small-team scale; running on infrastructure you already pay for; where the third-party option is extractive or abandoned.

Look at your own stack with that lens and candidates appear everywhere: the newsletter signup that’s a SaaS wrapping one POST endpoint, the contact form paying a monthly fee to send you an email, the link shortener, the uptime monitor - anything held together by a free tier that could be sunset by a product decision you’ll read about on Hacker News.

I’m not arguing for building everything. I didn’t build my own analytics - GoatCounter is maintained, principled, and better than what I’d write. The point is that “someone else runs it” is no longer automatically the safe answer, and “we’d have to build it” is no longer automatically the expensive one. Each dependency deserves two questions now: if this broke tomorrow, would I replace it or rebuild it? And: am I prepared to keep what I build alive? The answers have changed more than our habits have.

If you run a site on Azure Static Web Apps and want this without the afternoon of building, the whole system is open source at StaticWebComments - MIT licensed, quickstart README, gotchas documented so you don’t pay for them twice.

The comment box below this post is the new system. It would be fitting if you told me what you’d rebuild first - it’ll ping my phone when you do.