Writing from the workshop
42 articles on the parts that actually hurt.

You're collecting async iterable results with a for-await loop. Array.fromAsync does it in one call.
A for-await loop that pushes into an array, or the `await Promise.all([...asyncIterable])` workaround that silently fails — `Array.fromAsync` replaces both with a single awaited call. It's Baseline 2024.
Your browser renders everything, even what you can't see — content-visibility: auto fixes that
Aug 4 · 5 min SecurityCORS Explained: The Complete Guide (with Cheat Sheet)
Aug 3 · 14 min JavaScriptYour UI is freezing because you never gave the browser a break
Aug 3 · 4 min CSSYou're writing dark-mode colors twice. light-dark() fixes that.
Aug 2 · 5 min 
You've been wrapping new URL() in try/catch. URL.parse() does it natively.
Validating an untrusted URL before parsing it used to mean a try/catch wrapper or a regex. `URL.canParse()` checks validity without constructing. `URL.parse()` parses and returns null on failure. Both are Baseline 2024 — no wrapper needed.
Aug 1, 2026 · 5 min
CSS has no native scoping. @scope changes that.
BEM, CSS Modules, and scoped component styles all exist because CSS leaks — a rule written for one component can silently affect another. `@scope` gives the cascade a lower boundary so styles stay where you put them, natively, with no build step.
Jul 31, 2026 · 5 min
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.
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.
The classic fix for a headline that breaks awkwardly — a manual `<br>`, a `­`, 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.
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.
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