Stories, rants & insights
Longer-form pieces on Next.js, UI craft, and team habits. If you prefer action to theory, you will still find checklists and decisions you can borrow directly.
Streaming LLM Responses in the App Router
Token-by-token output, tool calls, cancellation, and resumable streams — the plumbing behind a chat UI that feels instant. Built on Web Streams, Server Actions, and the Vercel AI SDK, with the raw version underneath so you know what it is doing.
Shipping in Slices: How I Scope a Front-End Engagement
Most projects go sideways in the first two weeks, before anyone writes real code. Here is the scoping process I use to keep a build honest — written scope, vertical slices, and a definition of done that survives contact with production.
Partial Prerendering, Explained by Building One Page
PPR lets a single route be static where it can be and dynamic where it must be — one HTTP response, a prerendered shell with holes that stream in. Here is the model, and a product page built with it from scratch.
The View Transitions API for Real Apps
Native, GPU-accelerated transitions between DOM states and between pages — no animation library, no layout thrash. Here is how the API actually works, how to wire it into a Next.js app, and where it still bites.
The Data-Fetching Decision Tree for the App Router
Server Component fetch, Server Action, Route Handler, client fetch, or a library like React Query — the App Router gives you five ways to load data and very little guidance on which to pick. Here is the decision tree I actually use, with the code for each branch.
Design Tokens That Survive a Rebrand
A token layer is only worth building if it makes the next change cheap. Most do the opposite — they hardcode today's brand into a thousand component files. Here is how to structure tokens, in CSS, so a rebrand is an afternoon.
Forms That Don't Fight the User
Validation that fires on every keystroke, error messages that scold, a submit button that does nothing visible — forms are where products lose people. Here is how I build ones that get out of the way, with React Hook Form, Zod, and Server Actions.
Realtime Without a Realtime Service
Before you add Pusher, Ably, or a socket server: Postgres already has a pub/sub channel, and the browser has had Server-Sent Events for a decade. Here is a complete realtime pipeline — LISTEN/NOTIFY to SSE to the UI — with reconnection handled.
Core Web Vitals: A Field Guide for Real Products
Lab scores lie. Your Lighthouse 98 means little if real users on real phones are seeing an LCP of four seconds. Here is how I actually diagnose and fix INP, LCP, and CLS on shipping products — with the code and the CI wiring.
WebAssembly for Heavy Compute, Off the Main Thread
When a JavaScript loop is janking the UI — image processing, parsing, simulation, crypto — the answer is often Rust compiled to WebAssembly, running in a Worker. Here is the real setup: wasm-pack, Comlink, transferable buffers, and the parts that actually matter.
An Accessible Component Library Without the Overwhelm
You do not need to memorise WCAG to build an accessible component library. You need a handful of primitives done right and a short checklist applied consistently. Here is the version that fits in your head — with the code.
Wallet-Connect UX: Designing for the Unhappy Path
Connect, sign, done — that is the demo. Real Web3 UX is rejected signatures, wrong networks, stuck transactions, and RPCs that go quiet. Design the failure states first and the product feels trustworthy. Here is the code for each one.
Things to Stop Doing in Next.js in 2025
If you call yourself a mid-level Next.js developer and still write an API route for every form, sprinkle 'use client' like seasoning, and fetch inside client components — this one is for you. With the code for what to do instead.
Caching in the App Router Without the Footguns
Next.js caching has a reputation, most of it earned. But the model is learnable, and once you can name the four caches you stop being surprised by stale data. Here is the mental model plus the revalidation patterns I trust in production.
When to Reach for a State Manager (and When Not To)
Half the Redux stores I have deleted were holding server data that should have been a cache, and form state that should have been local. Here is a straight answer on where different kinds of state belong, with code for each.
Server vs Client Components, Kept Real
The Server/Client split confused almost everyone at some point — not because it is hard, but because people explain it like a compiler paper. Here is the plain-language version, plus the composition patterns that keep the boundary small.
Next.js Middleware Is a Doorman, Not a Firewall
middleware.ts is powerful, and most teams abuse it — redirecting every request, querying databases at the edge, and logging themselves into a self-inflicted outage. Here is what it is actually for, and the code to keep it fast.