
localStorage Is Not State: Persistence, Hydration, and Tabs That Fight Each Other
localStorage looks like a global variable that survives a refresh. That framing is the bug. Treat it as a persistence layer that mirrors your state — not as the state itself — and the hydration mismatches, stale tabs, and schema breakages mostly disappear.
Read full article →
Keeping a UI Kit Updated Across Apps: Versioning, Contracts, and Trust
A shared UI kit does not fail because the button component is hard to write. It fails when five applications are afraid to upgrade it. Versioning, contract tests, release channels, and migration paths are what turn a component library from a dependency into a product people can trust.
Read full article →
Changing a Component Everyone Uses: Deprecation, Codemods, and No Big-Bang Rewrites
Writing the new version of a shared component is the easy 10%. The other 90% is the hundred call sites that already depend on the old one — and the fear of touching them. Here's how I change a component everyone uses without a month-long rewrite that breaks the day it lands.
Read full article →
Headless Components: Give Away the Behavior, Keep None of the Markup
The most reusable UI code I write renders nothing at all. Headless components, render props, and hooks-as-API are three names for one idea: separate what a component does from how it looks — and hand over the behavior without a single opinion about the markup.
Read full article →
Compound Components: Designing an API, Not Just a Component
The moment a component grows past a handful of props, you're not writing a component anymore — you're designing an API. Compound components are how you keep that API flexible without drowning it in configuration props.
Read full article →
Is Container vs Presentational Dead? What Survived the Hooks Era
The pattern that taught a generation to split 'smart' from 'dumb' components got quietly declared obsolete when hooks arrived. It wasn't. The folder convention died. The idea underneath it is more useful now than ever — including in Server Components.
Read full article →
How Big Should a Component Be? Composition, Decomposition, and Handing Over Dependencies
Split a component too early and you get a maze of tiny files. Split too late and you get a 600-line monster. The real question isn't size — it's who owns which dependency, and whether the component reaches for it or is handed it.
Read full article →
The Direction of the Arrows: Dependencies Are Your Real Architecture
You can draw whatever folder diagram you like. The honest picture of your app is which module imports which — the direction of the arrows. Get that wrong and no folder structure will save you.
Read full article →
Barrel Files: The Import You Love and the Bundle You Hate
A barrel file makes imports look beautiful and can quietly drag half your app into a bundle that only needed one function. Here's what index.ts actually does, when it earns its place, and when it's a trap wearing a clean interface.
Read full article →
The shared/ Folder Is Not a Place, It's a Promise
Every codebase grows a shared/ folder, and given enough time every shared/ folder becomes a junk drawer. Not because the team got lazy — because the folder was never given a rule. Here's why it rots, and how to keep it boring.
Read full article →