Journal
Reflecting on some of the toughest challenges I've tackled in my career.

Errors Aren't Strings: Four Unfashionable React 19 Patterns
Most React codebases rhyme: inline error strings, forms that flash on submit, a Tailwind config quietly eating the design system. Four small patterns that compound — typed error codes, a Form wrapper, colocated copy, and no tailwind.config at all — and the UI layer finally behaves.

The AI Agent's Best Tool Is Fewer Tools
A capable model with ten tools burns through its step budget before it can answer anything. So Stir routes every query through a tiny classifier first, scopes the main model to a four-tool subset per intent, and short-circuits one-word queries with zero LLM calls.

I Haven't Written fetch() in a Year
Every React app has a fetch-shaped hole in it, and a 40 KB library to manage the cache you didn't need. RSVPed has zero client fetches: one server-side gateway, progressive RSC streaming, and transitions for everything else. Half the bundle, no waterfalls, no stale data.

Faker Gives You Fake Data. That's The Problem.
Faker fills columns; it can't tell stories. A three-pass LLM pipeline that generates relationally coherent demo data — food bloggers RSVP to wine tastings, high-spenders buy VIP tickets, friends actually share cities — for under two dollars a run through the Anthropic Batch API.

How to Monitor Cats Without Losing Your Sanity
When you've got two chaotic cats and four cameras with pathetic interfaces to monitor them, you either give up or build something better. This is a deep dive into the system I ended up building something to actually do what the default apps promise but never deliver.

SKUs, Variants, Payment Reconciliation & Existential Dread
The adventures of building a dynamic, CMS controlled furniture e-commerce backend where product variants multiply like rabbits, orders need to remember what they bought six months ago, and Stripe payments must never leave customers charged but orderless—all while keeping our frontend sane with type-safe automation.

Why Every IP Camera App Sucks (And How We Fixed It)
Most IP Camera apps are cluttered, laggy, and weirdly stubborn about layout or responsiveness. So we built our own: a clean, mobile-friendly control panel with real-time streaming, swipe gestures for pan and tilt, and just enough polish to not feel like a weekend hack.

Lilac: A Modern E-commerce Frontend That Doesn't Typecast
How we built a furniture e-commerce frontend that scales, performs, and doesn't make developers want to quit programming. From GraphQL code generation to payment orchestration, animation systems, and state management—the complete technical deep dive.

Death by a Thousand Tooltips
The trials and tribulations of building a high-performance, accessible overlay framework for enterprise legal software & achieving WCAG AA compliance - all with performance and customization at the forefront.

If You Can Fill a Spreadsheet, You Can Build an Assessment
We discuss the architecture of a sophisticated healthcare assessment platform that lets you create complex risk calculators without code using a matrix-based decision logic.

Next.js Saved Our Blog—and Probably Our Sanity
Learn how valuable eliminating runtime errors and improving performance is to establish development standards for a junior team, and how the Razzle.js to Next.js transition saved us.

How We Built Landing Page IKEA for Marketing Teams
How we transformed a 1.5-2 day landing page creation process into a 20-minute drag-and-drop experience using Strapi polymorphic components and dynamic routing.

WYSIWYG - unless you use tokens!
Optimizing a RoosterJS-based email editor that was suffering from performance issues, recursive event loops, and cursor instability when handling dynamic variables in recruitment email templates.

How I Learned to Stop Worrying and Love DOM Orchestration
In this case study, we explore some of React 19's wonderful quirks, DOM manipulation & learn why you should worry if your React code starts looking like jQuery.