Blog
Posts on software development, careers, and craft.
Why I enjoy React: I can use the parts I like, and replace the rest
Why I enjoy React: I can use the parts I like, and replace the rest. Don’t like useEffect or useState? No problem. Use third party state (react-que...
Tired of getting "could not resolve" errors when running npm install
Tired of getting "could not resolve" errors when running npm install? This is typically caused by a package that needs to update its peerDependenci...
Problem: The React docs encourage declaring anonymous functions in useEffect
Problem: The React docs encourage declaring anonymous functions in useEffect. This means the developer's intent isn't documented. 👎 Solution: Call...
Picking between px and em/rem in CSS has always confused me
Picking between px and em/rem in CSS has always confused me. This post by @JoshWComeau has finally made this decision clear! Summary: If the value...
Here's a React hook that checks if the user's device has a rear facing camera
Here's a React hook that checks if the user's device has a rear facing camera. Technique: Use the browser's getUserMedia API to check if facingMode...
Accessibility tip: Wrapping related form elements in a fieldset improves...
Accessibility tip: Wrapping related form elements in a fieldset improves accessibility. Example: Wrap radios in a fieldset with a legend. Then, scr...
I ❤️ Next and Remix
I ❤️ Next and Remix. Here's my take on @nextjs vs @remix_run in one image. What's interesting: I expect the list of unique benefits to get shorter...
PSA: React “concurrent mode” doesn’t exist
PSA: React “concurrent mode” doesn’t exist. It was proposed, but ultimately abandoned. Instead, React 18 gives us 2 hooks for declaring low-priorit...
Modern browsers support built-in form validation
Modern browsers support built-in form validation. Looks nice, right? But, many web developers don't use this built-in form validation. Here are 3 r...
Problem: With controlled React forms, every keystroke causes the form to...
Problem: With controlled React forms, every keystroke causes the form to re-render. This can lead to lag on long/expensive forms. Three solutions:...
Just learned about http://a11ysupport.io
Just learned about http://a11ysupport.io. Trying to write accessible web app? This site documents the features each screen reader supports. So it's...
I’m a @Cypress_io fan
I’m a @Cypress_io fan. But, it’s not perfect. 1. Can’t trigger keyboard tab key 2. Can’t switch in/out of iframes 3. Can’t hover 4. Can't test cont...
Developer experience (DX) metrics: 1
Developer experience (DX) metrics: 1. How fast is the feedback loop? 2. How fast are the tests? 3. Can devs code against local mocks? 4. How fast i...
Common scenario: A team has two types of tests: 1
Common scenario: A team has two types of tests: 1. Unit tests (testing functions and components in isolation, often via @fbjest) 2. In-browser test...
React hooks tip: Prefer primitives in dependency arrays
React hooks tip: Prefer primitives in dependency arrays. Doing so helps avoid needless re-runs. #react
Wow - I just converted a React component library build process from Rollup...
Wow - I just converted a React component library build process from Rollup to esbuild. Before, using Rollup: 33 seconds After, using esbuild: 8 sec...
You probably don’t need CSS media queries anymore
You probably don’t need CSS media queries anymore. Why? Because CSS has matured. We can go beyond mere responsive designs. Now, we can support *flu...
I'm a @remix_run fan
I'm a @remix_run fan. But, there are valid reasons to prefer @nextjs static builds for some sites: 1. Static files are simple 2. Static files are c...
🚨 I'm writing a new course
🚨 I'm writing a new course! 🚨 “Next.js 12: The Big Picture” This course is for anyone considering @nextjs. It covers what makes Next.js special,...
4 options for rendering in @nextjs: 1
4 options for rendering in @nextjs: 1. Static Site Generation (SSG) 2. Incremental Static Generation (ISG) 3. Server-side Rendering (SSR) 4. Client...
I just learned there is a 28,000 km (17k miles) long stretch of fibre-optic...
I just learned there is a 28,000 km (17k miles) long stretch of fibre-optic cable that runs all the way from the UK to Japan. It’s called FLAG (Fib...
I enjoyed this "TypeScript tips and tricks" episode with @mpocock1
I enjoyed this "TypeScript tips and tricks" episode with @mpocock1. He solves some seriously tricky typing problems with #typescript - including us...
Lerna is unmaintained
Lerna is unmaintained. So, here are 10 monorepo-related tools to consider: 1. @NxDevTools 2. @turborepo 3. @pnpmjs workspace 4. @yarnpkg workspace...
CSS Viewport height is complicated
CSS Viewport height is complicated. Summary: lvh: Largest viewport height (when browser UI is hidden) svh: Smallest viewport height (when browser U...
Are you unfamiliar with Edge hosting
Are you unfamiliar with Edge hosting? This is a wonderful intro. This post explains why @Cloudflare chose: 1. The V8 JavaScript engine 2. The servi...
Wow, TIL why Edge servers use V8 instead of Node
Wow, TIL why Edge servers use V8 instead of Node. It starts up 100x faster than Node. 🤯 This is huge. Not just because it's far lower overhead. Al...
Many teams say "accessibility is important", but don't actually test...
Many teams say "accessibility is important", but don't actually test accessibility. Why? They're "too busy". They don't know how to test accessibil...
3 ways to split a dev team that is too big: 1
3 ways to split a dev team that is too big: 1. Vertical: Each team owns a different vertical slice 2. Horizontal: Separate front and backend team 3...
Woah, just installed Fig
Woah, just installed Fig. Fig provides slick autocomplete in the Terminal. Only spent a few minutes with it so far, but I'm loving this so far. 👍...
This CSS reset by @JoshWComeau contains a lot of thoughtful little tricks
This CSS reset by @JoshWComeau contains a lot of thoughtful little tricks. I learned a lot just reading his justifications. https://www.joshwcomeau...