Robert Zehnder

I write about BoxLang, CFML and the JVM web stack, and build open-source modules and apps with them. This is where the notes, the deep dives and the projects live.

Recent writing

All writing →

Serving Sites from Your Dev Server

Side projects shouldn’t cost more than they have users. Here’s how I moved mine off a $75/mo hosting bill and onto Docker on my dev server: a Cloudflare Tunnel with no open ports, a trusted CF-Connecting-IP header, JVM memory sized from container limits, a deploy script that tests itself before it touches production, and encrypted off-site backups to R2. It’s not high availability. It’s a home server. But the bill is zero.

boxlang

Passwordless sign-in for BoxLang with bx-passkeys

Passkeys replace passwords with a key pair kept on the user's device, so there's nothing reusable to phish or leak. This step-by-step guide adds them to a BoxLang app with bx-passkeys. You install the module, create the table and configure the relying party, then wire up four calls: registrationOptions(), register(), signInOptions() and verify(). It also covers the browser helper, listing and removing passkeys, testing with a fake authenticator, and a production checklist.

boxlang

Everything Runs on My Dev Box Now, and That’s Fine

November means burning leftover time off on side projects. Feedhouse outgrew a $75/mo hosting bill it was never going to earn back, so everything now runs in Docker on my dev machine behind Cloudflare Tunnels. It’s faster, too, now that the database isn’t starving. And DismalThreads is back with a facelift after a launch nobody came to and more rewrites than I’d like to admit: Facebook for developers, minus the memes and the LinkedIn-ness.

boxlang

The JVM Was Calling System.gc() Behind My Back

Feedhouse, a small BoxLang RSS reader, was running up to 70 full GCs an hour with its heap a quarter full. The likely cause: when direct (off-heap) buffer memory reaches -XX:MaxDirectMemorySize, the JDK calls System.gc() itself, and I had capped it at 64 MB. Raising the cap to 128 MB cut full GCs to 2-5 an hour, past the point where the spike used to begin. How I tracked it down with hourly JVM metrics and an admin GraphQL API, driven by Claude Code.

boxlang

MacMD Viewer: a read-only Markdown viewer for reviewing what Claude writes

MacMD Viewer is a native, read-only Markdown viewer for macOS. Press space in Finder for a formatted Quick Look preview, or open a window with an outline, syntax highlighting, Mermaid diagrams and auto-reload. Being read-only is the point: you can read SKILL.md and REFERENCE.md files while Claude edits them, without an editor fighting over the file. $19.99, or included with Setapp.

claude

It’s Not the Chisel

After 40 years of writing code by hand, I looked down on vibe coding. Then I tried it. This is a look at what people mean by “AI slop,” which complaints hold up, what AI means for developers who are still learning, and why slop was never about how the code got written. An LLM is a chisel: in the right hands it makes something worth keeping, and in mine, a lump. AI didn’t create slop. It just made it cheaper to produce.

ai

Feedhouse gets public pages, comments and Webmentions

Feedhouse now has opt-in public pages at /u/yourname: the shares, highlights and bundles you choose, with an RSS feed and a Follow button. Add a name, bio, avatar and a rel="me" website link for Mastodon verification. Anyone signed in can comment on public shares, while earlier follower comments stay private. You can turn comments off and block people. Public shares also send Webmentions, so authors see who shared their posts. Nothing goes public unless you choose it.

Feedhouse

Everything Feedhouse Does, From the Boring Parts Up

A tour of everything Feedhouse does, from the boring parts up: adding feeds, folders and keyboard shortcuts, then search, read-later, highlights and stories shown once, then filters for what you never want to see, feed health, a reading-stats table of shame, sharing, bundles and the phone app. Then the good stuff: newsletters with an address of their own and no tracking pixels, and a podcast player that keeps going while you read. No algorithm required.

boxlang

Selected projects

All projects →

Feedhouse

A feed reader in the spirit of Google Reader: RSS, YouTube, podcasts, Mastodon and Bluesky, in the order they were published, with nothing ranking your feed.

BoxLang · BoxExpress feedhouse.app ↗

DismalThreads

A community of groups, posts and threaded comments, with friends, reactions and replies that update live.

BoxLang · BoxExpress · React dismalthreads.com ↗

boxlang-express

An Express.js-style web framework for BoxLang: routing, middleware, sessions, WebSockets and STOMP. Both apps above, and this site, run on it.

BoxLang module Docs