Blog

The Hidden Cost of Client Components in Next.js

A look at how 'use client' drags entire dependency trees across the network boundary, and how to audit the damage.

Streaming SSR Patterns for Large Lists

Techniques for progressively streaming server-rendered UI so users see content before the database finishes responding.

Debugging Prefetch Behavior in the App Router

Reading the Network tab like a professional to figure out what the router is actually prefetching and when.

Why Your Bundle Is Bigger Than You Think

Source-map explorer, import cost, and the day-to-day habits that keep JavaScript payloads honest.

A Practical Guide to Server Actions

Moving mutation logic into the server runtime without giving up end-to-end type safety or progressive enhancement.

From Pages to App Router: A Migration Story

Six months of incremental adoption, what surprised us, and what we would do differently the second time around.

Designing for Dark Mode Without Regret

Token choices, contrast checks, and the common traps that make dark mode feel like an afterthought.

Tailwind CSS v4: What Actually Changed

A short, practical tour of the new engine, configuration format, and how migration plays out in real apps.

Type-Safe Environment Variables at Scale

Why parsing env once at the edge of your program saves you hours of production debugging later.

Edge Runtime vs Node Runtime in 2026

Where each runtime wins, where they tie, and the handful of APIs that still make the choice for you.

Incremental Static Regeneration Explained

A mental model for stale-while-revalidate at the page level, with diagrams that finally make sense.

Structured Logging for Next.js Applications

Escaping console.log culture and giving your future self something searchable to grep through at 3am.

The Quiet Return of Monolithic Architectures

How teams are consolidating services without giving up the scalability benefits they spent years chasing.

Pragmatic Accessibility for Product Teams

A short list of habits that turn accessibility from a last-minute audit into an everyday design input.

Rewriting Our Auth Layer in a Weekend

What happens when you finally stop patching the session layer and give it the surgery it has been asking for.

Zero-Downtime Deploys on Vercel

Feature flags, preview URLs, and the quiet deploy choreography that keeps users from ever noticing a release.

Measuring Core Web Vitals That Actually Matter

Which metrics move product outcomes, which ones are vanity, and how to wire real user monitoring on a budget.

A Love Letter to the Command Palette

Why the humble Cmd+K overlay quietly became the most important piece of UI in the apps I use every day.

When to Reach for a State Machine

Signs your reducer is secretly a finite-state machine begging to be written as one, plus when to resist.

Taming Long Forms With React Hook Form

Patterns for multi-step, conditional, and dynamically-shaped forms that do not collapse under their own weight.

The Truth About React Server Components

A calm, spec-first explainer that cuts through the hype and names exactly what they are and are not.

Database Migrations Without the Panic

Expand-contract, shadow tables, and the small rituals that make schema changes feel almost boring.

Why We Stopped Using Barrel Exports

A single `index.ts` can quietly double your cold-start time. Here is what we replaced it with.

Writing Effective Pull Request Descriptions

Reviewing is expensive; the author pays the smaller cost of writing so the team pays the smaller cost overall.

Async Work Is Cultural, Not Technical

Tools only help if the team already believes written communication is the default. Here is how to get there.

Designing APIs You Will Not Regret

A checklist of questions that consistently surface the mistakes you only notice a year after shipping.

A Field Guide to Optimistic Updates

When to lie to your users for their own good, and how to gracefully admit it when the server disagrees.

Rate Limiting for the Paranoid

Token bucket, leaky bucket, and why most teams accidentally ship the wrong one for the traffic they have.

Feature Flags That Do Not Leak

Keeping flag logic out of the UI and close to the boundary, so cleanup is a delete rather than an archaeology dig.

The Subtle Art of Cache Invalidation

A walk through tag-based, time-based, and event-driven invalidation, with their respective failure modes.

Typing Third-Party Libraries Without Tears

Ambient declarations, module augmentation, and other escape hatches for when DefinitelyTyped lets you down.

Monorepos Are Not the Problem

Build graphs, caching, and ownership boundaries are. A monorepo just makes your existing problems visible.

The Case Against Global State

Half of your Redux store is server cache in disguise. The other half is probably URL state.

Shipping a Design System Nobody Hates

Why the component library is the easy part, and the governance is the hard part you will keep putting off.

Handling Money in JavaScript Safely

Integer cents, decimal libraries, and the one-line rounding bug that cost us a remarkably long afternoon.

Lessons From a Year of On-Call

What I learned about systems, humans, and sleep debt across twelve rotations of the pager.

Reading Stack Traces Like a Detective

Frame-by-frame habits that let you locate the real bug without scrolling past the first async boundary.

React Suspense in Real Applications

Where boundaries belong, what they accidentally break, and how to reason about fallback UI without hand-waving.

A Gentle Introduction to eBPF

Tracing syscalls, profiling the kernel, and understanding why your server is doing what it says it is doing.

Rust for the TypeScript Programmer

A translation dictionary for everyday concepts, so your first week of Rust is a head start rather than a wall.

The Life and Death of a Side Project

Why most weekend projects die on Sunday night, and the small habits that occasionally let one survive.

Interviewing for Senior Engineering Roles

Signals interviewers are actually looking for, and the way to surface them without rehearsing canned stories.

How We Cut Our CI Time in Half

Cache keys, test sharding, and three small YAML changes that gave a hundred engineers back an hour a day.

Practical OpenTelemetry for Web Apps

Spans, attributes, and the minimum viable instrumentation that makes a production incident merely annoying.

The Smallest Viable Kubernetes Cluster

When you finally outgrow your VPS, what the simplest self-hosted cluster looks like before it grows teeth.

Why Your Postgres Queries Are Slow

EXPLAIN ANALYZE, statistics, and the two or three patterns that cover most of the queries I get asked about.

Indexing Strategies That Pay Off Later

Partial indexes, expression indexes, and the ones you wish you had created before the table got interesting.

Migrating From Redux to Zustand

An incremental path that does not require a big-bang rewrite or a hiring freeze on the UI team.

Drawing Boundaries in a Fullstack App

Where the server ends, where the client begins, and how to stop your types from smearing across the line.

Unit Tests Are Not a Replacement for Thought

They catch regressions, not design mistakes. Here is the kind of thinking that still has to happen up front.

404 Not Found

This blog post simulates content that existed during `next build` but has since been deleted and on-demand ISR removed, clicking this will trigger `notFound()`

E2E Testing That Does Not Flake

Deterministic selectors, network stubbing, and the small investments that turn a red pipeline back to green.

A Sober Look at AI Code Assistants

Where they genuinely help, where they introduce silent regressions, and how senior engineers actually use them.

Prompt Engineering Is Just Engineering

Versioning, tests, and observability apply to prompts exactly the way they apply to the rest of your code.

Running LLMs Locally for Fun and Profit

A weekend setup that takes you from zero to a usable local chat interface without selling your graphics card.

Vector Databases Without the Hype

When a dedicated vector store earns its keep, and when a well-indexed Postgres column will quietly do the job.

Retrieval Augmented Generation In Practice

Chunking, reranking, and the evaluation loop that keeps your RAG pipeline from silently degrading over time.

Writing a Custom ESLint Rule From Scratch

AST basics, a worked example, and the small codemod that enforced a team convention better than any wiki page.

The Rise of Colocated Configuration

Why the config file nearest to the code it configures tends to win, and what that means for your repo layout.

A Short History of CSS Layout

From floats to grid, a tour of the bad decisions we made together and the better ones we eventually agreed on.

Container Queries Changed Responsive Design

Component-level media queries quietly replaced a decade of workarounds; here is how to actually use them.

Why I No Longer Use CSS-in-JS

A balanced retrospective on runtime styles, the benefits I miss, and the problems I stopped having.

Static Analysis Beyond TypeScript

Linters, codemods, and the underrated layer of tooling that catches the bugs types cannot reason about.

Code Reviews That Teach

Notes from a principal engineer who reviews more than they write, and what they have learned to leave alone.

On-Call Playbooks Worth Writing

The shape of a runbook that helps a sleepy human, not a confident one, and why the difference matters.

Incident Response Without Blame

How to run a post-incident review that produces durable learning instead of a lingering bad taste.

Architecting for Graceful Degradation

Designing systems where the first failure is a shrug, not a full outage that trends on social media.

The Underrated Power of Feature Branches

Why the shape of your branching strategy quietly determines the shape of the conversations your team has.

Chaos Engineering for Small Teams

Lightweight experiments that give you most of the Netflix benefits without any of the Netflix budget.

Secrets Management Without Vault

What you actually need before reaching for dedicated infra, and how far a cloud secret manager will take you.

A Tour of Browser Storage APIs

Cookies, localStorage, IndexedDB, and the one most people forget about until it would have been useful.

Service Workers Are Still Useful

Post-PWA hype, the quiet cases where a service worker is genuinely the right tool for the job.

Progressive Enhancement Is Back

Starting from HTML and layering JavaScript on top turns out to map surprisingly well to modern frameworks.

Hypermedia as a Sensible Default

What HATEOAS was trying to tell us, and why a thoughtful REST API still beats most JSON dumps on ergonomics.

HTMX For the Curious React Developer

A weekend exploration of a library that made me rethink which problems actually needed a bundler.

The Myth of the 10x Engineer

A careful look at what that label usually describes, and why naming it that way tends to make teams worse.

Remote First Is Not the Same as Remote Friendly

The policy differences that decide whether remote teammates are full participants or slightly inconvenient guests.

Writing Documentation Your Team Will Read

Cognitive load, scannability, and the small formatting habits that separate reference docs from write-only docs.

The Engineering Ladder We Wish We Had

Behaviors and outcomes rather than years, and why the difference is worth the several meetings it will take.

Managing Up Without Becoming a Politician

Straight talk about communicating with leadership in a way that serves your team without selling your soul.

Estimating Software Projects Honestly

Why ranges beat single numbers, why your gut is smarter than your Gantt chart, and when to admit you do not know.

A Postmortem of Our Biggest Outage

What happened, what we thought happened, and the five improvements we shipped in the following quarter.

Building a Personal Knowledge Base That Lasts

File formats, folder conventions, and a review cadence that keeps notes useful for longer than a semester.

Shell Tricks Every Developer Should Know

A short, opinionated list of incantations that quietly save an hour a week once they become muscle memory.

Git Workflows Reconsidered

Trunk-based, GitFlow, and the handful of questions that actually decide which one fits your team.

Why Conventional Commits Are Worth the Overhead

A small discipline with outsized payoffs in changelogs, release automation, and pull request review velocity.

Semantic Versioning Is a Social Contract

Why SemVer only works when publishers and consumers agree on what "breaking" means, and what to do when they do not.

Publishing a TypeScript Package in 2026

Dual ESM/CJS, `exports` fields, and the minimum setup that will not embarrass you on npm next week.

The Small Joy of Finishing Side Projects

A nudge toward shipping the imperfect version tonight rather than rewriting the landing page for another weekend.

Reading Papers Without Going Insane

A practical workflow for working engineers who want to stay current with research without pretending to be academics.

The Programmer's Guide to Deep Work

What the research does and does not say, and the small environmental tweaks that actually compound over months.

Tools I Use Every Day as a Staff Engineer

A calm, unsponsored list of software that has earned its place on my machine over the last several years.

A Letter to My Junior Self

The handful of habits and attitudes I wish someone had pushed me to adopt in my first two years of work.

The Art of Walking Away From Technical Debt

Not every shortcut deserves a rewrite. Here is how to tell which debts to pay down and which to simply retire.

Designing Email That Actually Renders

Table layouts, inline styles, and a short list of clients that will continue to break your heart anyway.

Running Background Jobs on the Edge

Queues, cron, and durable execution patterns for code that has to keep running after the request goes away.

The Forgotten Power of the HTTP Cache

ETags, Vary, and the headers your CDN is already willing to respect if you would only bother to set them.

Writing Fast Tests Without Cutting Corners

Test design choices that keep a suite under thirty seconds even as the product grows past a million users.

The Case for Boring Stacks

Why the most interesting work at most companies is built on the least interesting technology choices.