Blog

Posts on software development, careers, and craft.

A recipe for frustrating developers: 🚫 Require a slow VPN or slow remote...

A recipe for frustrating developers: 🚫 Require a slow VPN or slow remote virtual machine to work. 🚫 Forbid changing most things. We must accept p...

"This is a good suggestion, but it's outside the scope of this PR

"This is a good suggestion, but it's outside the scope of this PR. So I opened ticket 123 to address it." This is a wonderful PR response.

I’m reviewing a plain JS code base

I’m reviewing a plain JS code base. It contains over 1,000 uses of optional chaining: “?.” Why? Because they don’t feel they can trust the properti...

I just read this variable name in a code review:...

I just read this variable name in a code review: startLoadTabIsActiveAndHasNoErrorsButEndLoadTabHasErrors It's long, but I like it. I prefer descri...

Common React mistake: Buried default 🚫 Don’t bury the default inside the...

Common React mistake: Buried default 🚫 Don’t bury the default inside the component. ✅ Make the default part of the public API.

I work with multiple companies every week

I work with multiple companies every week. The teams I enjoy most: ✅ I work on my own laptop. ✅ The people I work with are good communicators. ✅ Ev...

Locality of Behavior (LOB) Principle: The behaviour of a unit of code should...

Locality of Behavior (LOB) Principle: The behaviour of a unit of code should be as obvious as possible by looking only at that unit of code. Locali...

So many bad takes on this photo

So many bad takes on this photo. SQL injection is protected via the “sql” call. If you don’t like inline SQL, you can abstract it by calling a func...

Problem: It’s easy to accidentally name a boolean in a way that makes it...

Problem: It’s easy to accidentally name a boolean in a way that makes it sound like a function. Example: showDialog. Instead, prefer isDialogVisibl...

The smaller the PR, the faster it gets merged

The smaller the PR, the faster it gets merged. ✅ Lower risk ✅ Less to review ✅ Easier to understand

Just learned about AutoAnimate

Just learned about AutoAnimate. Add motion to your app with one line of code. Works with all the popular JS frameworks too. Awesome work @jpschroed...

Just presented “Creating Reusable Components…That Are Actually Reusable” at...

Just presented “Creating Reusable Components…That Are Actually Reusable” at @connect_js. Here’s the slides! https://www.dropbox.com/scl/fi/vrtxhl4k...

Habit: When someone provides a detailed and helpful explanation in a pull...

Habit: When someone provides a detailed and helpful explanation in a pull request, I often ask them to paste it into the code as a comment. If it's...

A simple sign that a web app isn't using URLs effectively: Tickets can't...

A simple sign that a web app isn't using URLs effectively: Tickets can't merely specify a URL. Instead, they have to say 🚫 "Click on this tab" 🚫...

It’s common to store the active tab like this: activeTabIndex = 0; But this...

It’s common to store the active tab like this: activeTabIndex = 0; But this has downsides: 🚫 What tab does each index represent? 🚫 TypeScript can...

Avoid a single meeting on a problem

Avoid a single meeting on a problem. Instead, have two separate meetings: Meeting 1 - Define the problem. Meeting 2 - Decide how to fix the problem...

Poll: Which boolean variable name do you prefer

Poll: Which boolean variable name do you prefer? showX isXVisible The former is shorter, but sounds like a function. The latter is clearly a bool,...

Problem: If a function accepts multiple parameters of the same type, we may...

Problem: If a function accepts multiple parameters of the same type, we may accidentally pass arguments in the wrong order. Types can’t protect us....

Can someone show me a an HTML form that uses the browser’s native validation...

Can someone show me a an HTML form that uses the browser’s native validation APIs and: 1. Has custom styles for the native error messages so they l...

You’d be shocked how complex a web form can be

You’d be shocked how complex a web form can be. I’m looking at a simple web form with 5 fields that uses: useState useEffect Redux React Query Reac...

How a developer shows empathy: Have a sense of urgency in reviewing pull...

How a developer shows empathy: Have a sense of urgency in reviewing pull requests. Write code that's easy for others to understand. Offer to help w...

One of the hardest parts of being a developer is picking my battles

One of the hardest parts of being a developer is picking my battles. 🚫 The team picks an “inferior” tech 🚫 The boss decides to double the team si...

One of the most satisfying discoveries as a React dev: Needless prop drilling

One of the most satisfying discoveries as a React dev: Needless prop drilling. Me: "Hrmm, where is this prop coming from?" I trace up through 5 lev...

Problem: Sometimes people export internals merely to support unit testing

Problem: Sometimes people export internals merely to support unit testing. But, it's generally recommended to only test the public interface. And s...

When I see an optional React component prop in a code review, I dig deeper: 1

When I see an optional React component prop in a code review, I dig deeper: 1. What happens when the prop is omitted? Is there a default? 2. Is it...

I love cars and I love driving

I love cars and I love driving. I enjoy reading and watching car reviews - even for cars I’d never buy. Cars are awesome. But a city that prioritiz...

Wow, this was more lopsided than I expected

Wow, this was more lopsided than I expected. Out of 3,000 devs, 94% seldom or never use useReducer. And about half never use it. useReducer is grea...

Just used the new "Presenter Overlay" feature on MacOS Sonoma to create a...

Just used the new "Presenter Overlay" feature on MacOS Sonoma to create a short teaser for my "React State: 10 Years of Lessons Learned" talk. I do...

Atomic design is great

Atomic design is great. It provides useful terminology for creating and composing reusable components. But sometimes teams organize their reusable...

Problem: I use "test.only" to run a single test quickly

Problem: I use "test.only" to run a single test quickly. But if I forget to remove the "only" before committing, no other tests will run on CI. 😬...