Blog
Posts on software development, careers, and craft.
Prediction: React's upcoming `use` hook will be overused, just like...
Prediction: React's upcoming `use` hook will be overused, just like useEffect is today. Like `useEffect`, `use` should mainly be used "behind the s...
I finally bought a Thunderbolt 4 dock
I finally bought a Thunderbolt 4 dock. Loving it. All this connects to my M1 MacBook Pro via 1 cable: 1. 4K/60hz monitor 2. 4K SLR webcam 3. Audien...
React’s “use” hook in 1 tweet: Works like “await”
React’s “use” hook in 1 tweet: Works like “await”. Wraps promises (and soon other things). The component replays when the promise resolves. Only fo...
Hiring a company to do software development is risky
Hiring a company to do software development is risky. Why? Because "Done" is hard to define. Consider aspects of software quality: Fast Secure Usab...
Naming is hard
Naming is hard. The solution? Nouns vs verbs. Start these with a verb: Functions ➡️ getUser Ticket titles ➡️ Fix log out Commit messages ➡️ Fix bug...
TypeScript tip: Avoid making a property optional when the property isn’t...
TypeScript tip: Avoid making a property optional when the property isn’t valid in a certain case. Instead, declare 2 separate types, and use Omit t...
Compiling #TypeScript is slow
Compiling #TypeScript is slow. My solutions: 1. Don't run tsc during dev. (Lean on editor) 2. Use incremental flag when watching files. 3. Decompos...
I’m really enjoying @turborepo
I’m really enjoying @turborepo. It’s a game changer. With Turbo, I have an incentive to break my repo down into many small, focused packages. This...
One of my favorite VS Code plugins: Code spell checker
One of my favorite VS Code plugins: Code spell checker. I've been shocked at how many spelling errors it has caught in the last few weeks. It has h...
I'm reviewing a React codebase that uses Redux to cache HTTP responses
I'm reviewing a React codebase that uses Redux to cache HTTP responses. It feels needlessly complex, and risky. And, there's no cache invalidation...
Code smell: Frequently checking for null/undefined
Code smell: Frequently checking for null/undefined. The root cause: Inconsistent data/settings. When data is inconsistent, I normalize it before us...
TypeScript tip: Prefer type declarations to type assertions
TypeScript tip: Prefer type declarations to type assertions. Type assertions ignore excess properties. 👎 Type declarations check for excess proper...
5 ways to unit test a React component today: 1
5 ways to unit test a React component today: 1. @fbjest with @TestingLib 2. @vitest_dev with @TestingLib 3. @storybookjs with 1 or 2 above 4. @Cypr...
TypeScript tip: Read “extends” as "equals", “assignable to”, or “subset of”
TypeScript tip: Read “extends” as "equals", “assignable to”, or “subset of”. So read this: function getKey<K extends string>(Val: any, key: a...
Problem: When using a third party component library, it's common to set the...
Problem: When using a third party component library, it's common to set the same props each time you use a component. Solution: Wrap it. Benefits:...
React tip: Group related props
React tip: Group related props. Example: If two props are optional, but both must be set if used, group them via an object. This way, the related p...
Code coverage can lie
Code coverage can lie. 100% coverage doesn’t mean all code is covered. One solution: Mutation testing. Mutation testing changes the code to assure...
React tip: Avoid using useEffect to sync state
React tip: Avoid using useEffect to sync state. Instead: 1. Derive values on render 2. Handle logic in events I just eliminated these 3 useEffect c...
Types are tests with better ergonomics
Types are tests with better ergonomics. Types provide faster feedback, inline, with less code than the equivalent test would require. Types don't r...
Problem: How do I find unused packages in package.json
Problem: How do I find unused packages in package.json? Answer: Use depcheck. It reports unused packages, and reports packages that should be insta...
Tailwind feels as logical as Prettier
Tailwind feels as logical as Prettier. Prettier ✅ Save time by auto-formatting code ✅ Eliminate decision fatigue ✅ Easily switch projects ✅ Code fa...
My React folder pattern: 1
My React folder pattern: 1. The component folder structure mimics the routing structure. Result? Easy to find! 2. Exception: Reusable components in...
I've been working in React for nearly a decade
I've been working in React for nearly a decade. But over the years my approach has radically evolved. Classes ➡️ functions Mixins ➡️ hooks prop-typ...
Tip: Using TypeScript in VS Code
Tip: Using TypeScript in VS Code? Here are 5 places to check for TS compiler errors. And watch out, many of these spots but may be hidden at times....
I’m creating a new course
I’m creating a new course! 🎉 “React: The Good Parts” Idea: 1. Learn modern React quickly. 2. Build a realistic app from scratch. 3. Use only React...
Just converted a test suite from Jest to Vitest
Just converted a test suite from Jest to Vitest. The process: 1. Create vite.config.ts. Enable globals. 2. Replace “jest” with “vi” in tests. Resul...
React: The Good Parts™ Core API: 1
React: The Good Parts™ Core API: 1. Function components 2. JSX 3. useState 4. useReducer 5. useRef 6. lazy 7. Suspense Ecosystem: 1. TypeScript 2....
This TypeScript story sounds familiar
This TypeScript story sounds familiar. Summary: 1. Adopt TypeScript. 2. Overuse "any". 3. Think TypeScript is useless. 4. Later realize...the probl...
How I test a pull request for "Robustness": I enter malformed data
How I test a pull request for "Robustness": I enter malformed data. I enter in a lot of data. I submit empty data. I slow the network. I disable th...
It’s easy to overlook issues in code reviews
It’s easy to overlook issues in code reviews. So, I use a high-level checklist: DRY Usable Secure Tested Robust Readable Accessible Performant Conf...