The blog

Writing from the workshop

119 articles on the parts that actually hurt.

section
Array methods are eager. Iterator helpers are lazy. Here's why that matters.
JavaScript

Array methods are eager. Iterator helpers are lazy. Here's why that matters.

Every `.map()` and `.filter()` on an array creates a new intermediate array. Iterator helpers — built into JavaScript since 2024 — give you the same pipeline but evaluate one element at a time, with no wasted allocations.

Jul 30, 2026 · 5 min
You reach for Sass to mix colors. `color-mix()` does it natively.
CSS

You reach for Sass to mix colors. color-mix() does it natively.

Sass's `darken()`, `lighten()`, and `mix()` functions solved real problems CSS couldn't handle for decades. `color-mix()` is the native answer, and it ships in every modern browser with no build step required.

Jul 29, 2026 · 4 min
You hand-edit headlines to avoid orphaned words. `text-wrap: balance` does it natively.
CSS

You hand-edit headlines to avoid orphaned words. text-wrap: balance does it natively.

The classic fix for a headline that breaks awkwardly — a manual `<br>`, a `&shy;`, or a max-width tweak — exists because CSS had no way to distribute line breaks evenly. `text-wrap: balance` and `text-wrap: pretty` are the native answers.

Jul 28, 2026 · 4 min
You're watching `window` to detect element size changes. `ResizeObserver` watches the element itself.
JavaScript

You're watching window to detect element size changes. ResizeObserver watches the element itself.

A `window` resize listener only fires when the viewport changes. ResizeObserver fires whenever the element's own box changes — from content loading, parent reflow, container queries, or anything else.

Jul 26, 2026 · 4 min
You use a setTimeout to trigger CSS entry animations. `@starting-style` makes it unnecessary.
CSS

You use a setTimeout to trigger CSS entry animations. @starting-style makes it unnecessary.

Before `@starting-style`, the moment an element entered the DOM was invisible to CSS — transitions had no 'before' state to interpolate from. The at-rule gives you one, natively, with no JavaScript required.

Jul 25, 2026 · 4 min
You still write `finally { resource.close() }`. The `using` keyword does it automatically.
TypeScript

You still write finally { resource.close() }. The using keyword does it automatically.

The Explicit Resource Management proposal adds a `using` declaration that calls cleanup the moment a scope exits — normal return, early return, or throw. No more try/finally boilerplate for timers, event listeners, connections, or any other resource you need to release.

Jul 24, 2026 · 4 min
You've been doing Set math by hand. JavaScript finally shipped `.union()`, `.intersection()`, and friends.
JavaScript

You've been doing Set math by hand. JavaScript finally shipped .union(), .intersection(), and friends.

Set has always been missing its obvious operations. ES2025 adds `.union()`, `.intersection()`, `.difference()`, `.symmetricDifference()`, and three boolean predicates — native methods that used to require four lines of spread syntax each.

Jul 23, 2026 · 4 min
You keep escaping the Promise constructor. `Promise.withResolvers` does it right.
JavaScript

You keep escaping the Promise constructor. Promise.withResolvers does it right.

The 'deferred promise' pattern — storing resolve and reject outside the constructor so you can call them later — is a daily JavaScript idiom that's always felt awkward. ES2024 added a one-liner for it.

Jul 22, 2026 · 4 min
You're rethrowing errors and losing context. `Error.cause` fixes that.
JavaScript

You're rethrowing errors and losing context. Error.cause fixes that.

Every time you catch an error and rethrow a new one without forwarding the original, you lose the stack trace, the error type, and everything useful about what actually went wrong. ES2022 added `Error.cause` to fix exactly this.

Jul 21, 2026 · 4 min
TypeScript Generics: The Complete Guide (with Cheat Sheet)
TypeScript

TypeScript Generics: The Complete Guide (with Cheat Sheet)

Learn TypeScript generics from the ground up — generic functions, constraints, defaults, and classes — with worked examples and a copy-paste cheat sheet.

Jul 20, 2026 · 15 min
Your scroll listener fires on every pixel. `IntersectionObserver` fires when visibility actually changes.
JavaScript

Your scroll listener fires on every pixel. IntersectionObserver fires when visibility actually changes.

Detecting whether an element is in the viewport by listening to scroll events runs an expensive layout calculation on every frame. `IntersectionObserver` is the browser-native alternative — it fires only when visibility changes, off the main thread, with no scroll handler involved.

Jul 19, 2026 · 4 min
You're using Floating UI to position your tooltip. The browser does it natively now.
CSS

You're using Floating UI to position your tooltip. The browser does it natively now.

CSS Anchor Positioning is Baseline 2026 — it lets any element declare itself an anchor and any floating element position relative to it in pure CSS. No JavaScript, no layout math, no ResizeObserver wiring.

Jul 18, 2026 · 5 min