Blog
Posts on software development, careers, and craft.
Problem: You want to use Node with TypeScript
Problem: You want to use Node with TypeScript. Solutions: tsc (compile, then run js via node) ts-node tsx Bun esbuild swc babel-node vite-note My f...
The State of Frontend 2024 report is out
The State of Frontend 2024 report is out. Lots of interesting insights. Also, this year I was invited to write a summary of the automated testing r...
Next.js and React Router 7 (RR7) have fundamentally different approaches to...
Next.js and React Router 7 (RR7) have fundamentally different approaches to decomposition. In Next.js, you decompose via files. In React Router 7,...
React 19 is in RC React compiler is in Beta Tanstack Start is in Beta React...
React 19 is in RC React compiler is in Beta Tanstack Start is in Beta React Router 7 is in pre release So much good stuff coming soon! 2025 is goin...
I often talk to developers who are thinking about going independent
I often talk to developers who are thinking about going independent. My advice: 1. Build a business while you have a full-time job. 2. Don’t quit y...
Tanstack Query pattern: 1
Tanstack Query pattern: 1. Colocate related queries and mutations 2. Centralize queryKeys If a query sets a key, and a mutation invalidates the sam...
Knip finds unused JS and TS code
Knip finds unused JS and TS code. It's wonderful. But here's a tip: Configure Knip to ignore your tests. This way, if you have code that's only ref...
React 19 RC1 is out
React 19 RC1 is out. Suspense siblings prerender! When a component suspends, React commits the fallback of the nearest Suspense boundary without wa...
It's 2024 and I still see keys like this in React PRs
It's 2024 and I still see keys like this in React PRs. A key that changes on every render is worthless. Use something stable like a primary key, or...
Problem: I want to test my React app's error boundaries
Problem: I want to test my React app's error boundaries. Solution: Force an error via search params. This hook throws an error when a "throwError"...
Tanstack query is awesome for fetching and caching data
Tanstack query is awesome for fetching and caching data. But, it's broader than that. It's an *async state* library. Example: Here's a custom React...
Studio setup 2.0: - Closed blinds (to control the light) - New 5600K...
Studio setup 2.0: - Closed blinds (to control the light) - New 5600K keylight & backlight - Camera white balance at 5600K - New camera angle (h...
Mistake: Needlessly wide optional field
Mistake: Needlessly wide optional field. What's the semantic difference between an omitted address property, a null address, an undefined address,...
If I can’t clearly explain why people vote differently than me, then I need...
If I can’t clearly explain why people vote differently than me, then I need to research more. It’s not love vs hate. It’s not good vs evil. It’s no...
All these years I've been using "new Error" for nothing
All these years I've been using "new Error" for nothing!? Just learned that these are equivalent in JS: throw Error('oops') and throw new Error('oo...
In code reviews, I've learned to watch out for many related useState calls...
In code reviews, I've learned to watch out for many related useState calls in the same component - especially when they're booleans. Multiple useSt...
One of the most unkind things you can do is disparage someone else’s passion
One of the most unkind things you can do is disparage someone else’s passion. We all enjoy different things. We all need to find a reason to get up...
I've spent the last few weeks trying all sorts of React 19 edge cases
I've spent the last few weeks trying all sorts of React 19 edge cases. (publishing vids on this soon) Realization: I rarely need useState anymore....
TypeScript has a structural type system, not a nominal type system
TypeScript has a structural type system, not a nominal type system. What's that mean? When determining if a type "fits", the type's *structure* mat...
I have a theory: 🌶️Some developers are letting their political views impact...
I have a theory: 🌶️Some developers are letting their political views impact how they write code. Avoid associating ideas with people. Evaluate ide...
Two popular, but conflicting programming styles: Small functions vs deep...
Two popular, but conflicting programming styles: Small functions vs deep functions. The book “Clean Code” argues for small functions: “The first ru...
TypeScript problem: Related object properties should either all be provided,...
TypeScript problem: Related object properties should either all be provided, or all omitted. Two solutions: 1. Nest them under an optional object....
New React framework: One
New React framework: One. In this episode, I talk to One’s lead developer, Nate Wienert. What makes One special? - Do React and React native in the...
“Code should be obvious
“Code should be obvious. If someone reading your code says it’s not obvious, then it’s not obvious, no matter how clear it may seem to you.” - John...
Refactoring without tests is basically this: “I changed some stuff and...
Refactoring without tests is basically this: “I changed some stuff and hopefully didn’t break anything”. Risky business.
I don’t ask for permission to refactor
I don’t ask for permission to refactor. I don’t ask for permission to optimize performance. I don’t ask for permission to make it secure. I don’t a...
PSA: 📢 The useId hook is stable in React 18
PSA: 📢 The useId hook is stable in React 18. So, you don't have to write your own logic for unique ids in reusable components. Quite handy for ass...
Goal: Calculate a value once per render
Goal: Calculate a value once per render. Mistake: Declaring a parameterless function. Why? Because then the function may be needlessly called multi...
Problem: The backend API returns poorly structured JSON
Problem: The backend API returns poorly structured JSON. Solution: Ideally, fix the backend. But if we can't, I reformat the data in the response h...
Skeleton screens improve perceived load times, reduce bounce rates, and can...
Skeleton screens improve perceived load times, reduce bounce rates, and can reduce layout shift. But in practice, I've found skeleton screens are h...