I do a lot of things. Networks, firewalls, servers, Kubernetes, web development — I can work across all of it. The constraint isn't capability, it's time. Ten-hour work days, two hours of driving, and whatever sleep I can manage leaves about four or five hours to myself each evening. That's the window for everything else — eating, existing, talking to people, and building things.
When three websites needed to either get built or significantly overhauled in the same stretch of time, I needed to move fast. That's where Claude came in — not as a replacement for knowing what I was doing, but as a way to turn a clear technical direction into working code without spending three evenings on boilerplate. I'd describe what I wanted, review what came out, correct it, and iterate. The decisions were mine. The typing was shared.
Here's what shipped.
cmunroe.us — Migrating Away from Hugo
This site used to be a Hugo static site hosted on GitLab Pages. It worked fine, but I'd hit the ceiling of what I wanted to do with it. Hugo is great if you want a static blog and nothing else — but I wanted server-side rendering, a contact form, an RSS feed, a real sitemap, JSON-LD structured data, and a portfolio section with live screenshots. Static generation was fighting me at every step.
So I rewrote it from scratch in Node.js and Express. No framework, no CMS, no build step. Markdown posts live in content/posts/ as plain files with YAML frontmatter. The server reads them at startup, caches them in memory, and renders HTML on request. Gray-matter for frontmatter parsing, marked for the Markdown-to-HTML conversion.
The things I added that Hugo would have made painful:
- Server-rendered post pages with a table of contents generated from headings, reading time estimates, and related posts matched by overlapping tags
- Portfolio with live screenshots — fetched from the WordPress mshots service, cached to disk, served through an internal API endpoint so the browser never makes external requests. A polling loop on the portfolio page swaps placeholders for real screenshots once they're ready.
- GitLab commit graph in the sidebar — pulled from the public calendar JSON endpoint and rendered as a colour-coded grid of the last 13 weeks
- Contact form with rate limiting, nodemailer for SMTP, and a dedicated
/api/screenshot/:name/statusendpoint that the client polls
The whole thing deploys as a Docker image to K3s. Two replicas in production, one in staging, Keel watching the registry for updates.
heatherdesmond.com — Getting Mom Back on the Map
Heather — my mom — is a Broker Associate at Home & Ranch Sotheby's International Realty on the Central Coast. Her previous website provider had stopped maintaining her site. It was effectively abandoned, and that meant she had no real web presence at a time when buyers and sellers absolutely search for agents online before making a call.
This one had been sitting on my project list for a while. I knew she needed something and I wanted to do it for her — but between the day job and everything else, it kept getting pushed. With Claude in the mix, I was finally able to carve out the time to make it happen.
The goal wasn't just to get something live. It was to get her found. That meant proper SEO from the ground up — server-rendered pages with structured data and JSON-LD so Google understands who she is and what she does, a sitemap, canonical URLs, Open Graph tags for social sharing, and individual property pages with enough content for search engines to index. Each listing has its own URL with photos, location, and details rather than everything buried behind a JavaScript wall.
The result is a site that actually shows up when someone searches for a real estate agent in her area — which is exactly what an abandoned website wasn't doing.
addisonrealm.com — Cosmetologist Portfolio
Addison is a cosmetologist in Ventura, CA. A site for her had been on my uncle's list for a long time — one of those things that never happened because there wasn't a window to actually sit down and do it. We ended up building it during a family trip, knocking it out in a few hours with Claude handling the implementation while I directed what I wanted. That's exactly the kind of thing this workflow makes possible.
This one is the simplest of the three architecturally — Node.js and Express serving static HTML, with a PostgreSQL-backed contact form and a lookbook gallery. The interesting piece is the image handling. Clients send iPhone photos which are several megabytes each. The server runs sharp on startup to generate optimised thumbnails and resized versions — but we ran into an OOMKill early on and had to troubleshoot it. The culprit was sharp decoding multiple full-resolution images concurrently, blowing the memory limit. The fix was straightforward once we identified it: process one at a time. The lookbook page loads thumbnails and opens full-size optimised images in a lightbox with keyboard navigation and swipe support.
The contact form pre-selects the service dropdown based on a URL query param — the services page links to /contact/?service=extensions and so on. Small thing, but it makes the form feel intentional rather than generic.
The Common Thread
All three sites share the same general architecture — Node.js, Express 5, no frontend build step, Kubernetes deployment, Cloudflare Tunnel for external access. That's not a coincidence — I already had this pattern established across other projects in my monorepo, and Claude built directly on top of it. Rather than starting from scratch or inventing something new, it took the common structure I'd already proven out and iterated on it quickly. The consistency makes maintenance easier too — when something needs fixing, I know exactly where to look across all three codebases.
Testing is another area where the workflow paid off. I'd written tests before for other apps in the repo, so the pattern wasn't new to me — but setting up Vitest and Supertest, mocking the right dependencies, and getting the CI job wired in correctly is the kind of thing that can eat an hour of fussing. Claude handled the setup and wrote the test suite without me having to think about it. No wrestling with the scaffolding, no testing the tests — just coverage that actually runs in the pipeline.
Mobile was the most tangible example of how useful it is to have something diagnose and implement at the same time. I described what was broken — sidebar appearing before content, touch targets too small, nav collapsing wrong — and the fixes came back ready to go. Hamburger nav, 44px minimum touch targets, sensible breakpoints, layout order corrected. Issues that would normally mean opening DevTools, identifying the rule, fixing it, checking on three screen sizes, and repeating — handled in one pass.
Three sites live in production in one week is a reasonable pace — and a big part of what made that possible is that deploying to K3s is genuinely easy when the infrastructure is already in place. Flux CD watches the repo and reconciles cluster state automatically. A new app means writing the manifests, adding a Flux Kustomization, and pushing — Flux handles the rest. Keel takes it from there on every subsequent push, polling the registry and rolling out new images without any manual intervention. The cluster does the work; I just have to get the code there.
What's next: PostgreSQL backups, Loki log aggregation, and probably a few more posts about things that went wrong.