Writing

76 articles on BoxLang, CFML, the JVM and the tools around them.

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

Shopify API 2026-10 Changes

Shopify's 2026-10 API is stable. Breaking changes: address edits on unfulfilled orders now recalculate taxes, draft order PriceRule is gone, invalid metafield filters now error instead of being ignored, carrier services no longer auto-join the General profile, and FULFILLMENT_NOT_REQUIRED joins the status enum. ProductVariant.barcode gives way to barcodes. Additions include multi-tracking order imports, Shopify Payments fee details, and a new subscription calculation flow.

cfml

Shopify GraphQL: Order Ingestion & Updates

A reference for Shopify GraphQL order work in CFML. Covers GIDs, cost-based rate limits, and why HTTP 200 means nothing without checking userErrors. Ingestion: webhooks, paginated queries, bulk operations. Updates: orderUpdate, order edits, fulfillmentCreate, orderCreate for marketplace imports. Includes a CFC harness using script-based cfhttp, with one retry on THROTTLED. Notes the 2026-10 address-triggers-tax-recalc change.

cfml

My blog joined the fediverse

This blog is now on the fediverse as @blog@kisdigital.com. Follow it from Mastodon and new posts, edits and deletions reach your timeline within minutes; replies come back here as comments, and likes and boosts are counted. It's all powered by bx-activitypub, a new BoxLang module on ForgeBox and GitHub: your app answers four questions about its data and the module handles WebFinger, HTTP Signatures and delivery. Here's how it works, what I learned, and what's next.

boxlang