Blog

Posts on software development, careers, and craft.

For years, I’ve said “You don’t need a React form library

For years, I’ve said “You don’t need a React form library. You need a pattern.” I still believe that. But, I’ve been using React Hook Form more lat...

In one of my first dev jobs, I supported activating new cell phones at...

In one of my first dev jobs, I supported activating new cell phones at Sprint (later acquired by T-Mobile). My team supported software that sent ne...

Imagine you’re building a React app

Imagine you’re building a React app. How do you decide between these two options: 1. Traditional SPA 2. React Server Components (RSC) SPA benefits:...

How I start a new React app in 2024: Traditional SPA: Vite, Typescript,...

How I start a new React app in 2024: Traditional SPA: Vite, Typescript, @tan_stack file-based router. I’d add @tan_stack query if many pages use th...

Here's what makes @tan_stack Router special: It's the first React router...

Here's what makes @tan_stack Router special: It's the first React router designed to work with TypeScript. The API feels "weird" at first. Then you...

I've taught teams React with React Router for years

I've taught teams React with React Router for years. Today I'm using @tan_stack Router instead. We're using the file-based approach. It's quite nic...

Some developers are better than others

Some developers are better than others. WAY better. The difference is obvious. Some developers frequently deliver broken, confusing code that's nee...

4 attributes of scary code: 🚩 Feels needlessly complex 🚩 Unclear intent 🚩...

4 attributes of scary code: 🚩 Feels needlessly complex 🚩 Unclear intent 🚩 No tests 🚩 Buggy 😬 This is a scary combo. It often means we're hesit...

Naming matters

Naming matters. But it's easy to accidentally use inconsistent names in code. Examples: -tab, route, section, panel -user, customer, account Incons...

Problem: In TypeScript, developers often declare needless conditionals

Problem: In TypeScript, developers often declare needless conditionals. Why needless conditionals are a problem: 🚩 Adds noise 🚩 Hurts readability...

It's fascinating how many people either love or hate this take

It's fascinating how many people either love or hate this take. Some said it's "impossible to read". I don't get it. If I read the code top-down, o...

Order isn’t natural

Order isn’t natural. Chaos is. So, maintaining an orderly code base is a daily struggle. I've found these practices help maintain order: ✅ Communic...

3 ways to share code in React: Problem: Two components have different logic,...

3 ways to share code in React: Problem: Two components have different logic, but nearly identical JSX. Solution: Create a reusable component that c...

Problem: Using a laptop on a flight is cramped and the screen is too low

Problem: Using a laptop on a flight is cramped and the screen is too low. Solution: Use a laptop stand. I use "The roost". I find typing this way s...

Nested ternaries aren’t good or bad

Nested ternaries aren’t good or bad. They’re contextual. A nested ternary that contains 100’s of lines of code? Yuck. 🤮 A nested ternary that cont...

“It's already bad, so who cares." Teams don't say this out loud, but it...

“It's already bad, so who cares." Teams don't say this out loud, but it quietly happens all the time. Examples: 🚩 Ignore tests 🚩 Ignore usability...

Problem: Cache invalidation is hard

Problem: Cache invalidation is hard. Example: One of my clients uses React Query heavily. We have 100's of query keys, and many are quite complex....

In JavaScript, a pure function relies only on args

In JavaScript, a pure function relies only on args. It references no outside state. So, it always returns the same output for a given input. Pure f...

Ways I share data between React components: I prefer: ✅ Read/write to the...

Ways I share data between React components: I prefer: ✅ Read/write to the URL ✅ Pass values and callback functions via props ✅ Use a library that c...

Theory: We know pair programming is effective

Theory: We know pair programming is effective. But, most developers prefer working alone. So chances are, we don't pair as often as we should. How...

Problem: You want to know how much of your TypeScript code is type safe

Problem: You want to know how much of your TypeScript code is type safe. Solution: type-coverage This CLI tool reports the percentage of your code...

In TypeScript, I often prefer to use a Record over a switch statement

In TypeScript, I often prefer to use a Record over a switch statement. ✅ It's easy to read. ✅ It's typically less code. ✅ It's safer. With a switch...

Five terms I avoid when naming things: 1

Five terms I avoid when naming things: 1. data 2. info 3. item 4. object 5. entity These terms are so generic that they’re useless. I avoid using t...

I rarely use plain “any” in TypeScript

I rarely use plain “any” in TypeScript. Why? Because *anything* is typically too broad. Usually a more specific “any” is possible. 4 alternatives t...

I run every PR as part of my code review

I run every PR as part of my code review. Why? Because often, the PR doesn't even work right. Often a PR only works on a "happy path". It ignores v...

Needless React props = needless complexity

Needless React props = needless complexity. Example: 1. A component is intended for one use. 2. It accepts accepts a prop that *isn't used by the p...

Choosing a dynamic language over a statically typed language is like...

Choosing a dynamic language over a statically typed language is like choosing to drive instead of fly. Dynamic languages save time in the short run...

Problem: VSCode uses its built-in TypeScript version by default

Problem: VSCode uses its built-in TypeScript version by default. So if your project uses a different TypeScript version, people may experience type...

I spent more time with @tan_stack Router 1.0 on a long flight today

I spent more time with @tan_stack Router 1.0 on a long flight today. This is big. ✅SSR ✅Caching ✅Context ✅Data loaders ✅Error handling ✅Code splitt...

Just tried @tan_stack Router 1.0

Just tried @tan_stack Router 1.0. I'm impressed. A few of my favorite things so far: ✅ Type safe routes ✅ Optional file-based routes via a CLI ✅ Sl...