Esc
  • Design SystemsFrom Figma Variables to Tailwind, Without the Copy-PasteDesign tokens only help if design and code read from the same source. Here's how I set up a pipeline where Figma variables become Tailwind theme values and React props, and what I learned about naming along the way.
  • Next.jsBuilding a Like Button, From Database to DelightThe heart at the bottom of every article on this site is a tiny full-stack feature. Here's how it works, from the SQLite table and API route to optimistic updates and batched requests.
  • AnimationA Friendly Introduction to Spring PhysicsSprings make interfaces feel alive. Instead of picking a duration and an easing curve, you describe how something should move, and physics does the rest. Let's build an intuition for stiffness and damping with a live playground.
  • UI DesignDesigning Dashboards People Can Actually ScanData-heavy screens fail when every number shouts at once. A practical guide to hierarchy, tables, filters and progressive disclosure for dashboards that engineers and analysts use all day.
  • CSSUnderstanding Flexbox Alignment, Visuallyjustify-content or align-items? Main axis or cross axis? If you still guess which property to use, this interactive guide will fix that for good.
  • BrandA Brand System Is More Than a LogoA logo is the smallest part of a brand. What makes a brand recognizable is the system around it, from type and color to iconography, voice and the way the product itself behaves. Here's how I approach building one that survives contact with real products.
JavaScript

Five Underrated JavaScript APIs You Can Use Today

Deep cloning without libraries, grouping arrays in one line, human-friendly relative dates. The platform has quietly gained some excellent built-ins. Here are my favourites.

2 min read…

Every year, JavaScript picks up a few new built-ins that make an old utility library unnecessary. They rarely get much fanfare, so here are five that I reach for all the time.

structuredClone for real deep copies

The old trick of JSON.parse(JSON.stringify(obj)) silently breaks dates, maps, sets and anything with circular references. structuredClone handles all of them:

JS
const original = {
  createdAt: new Date(),
  tags: new Set(["css", "react"]),
};
original.self = original; // circular!

const copy = structuredClone(original);
copy.createdAt instanceof Date; // true
copy.self === copy;             // true

It can't clone functions or DOM nodes, but for plain data it's exactly what you want.

Object.groupBy

Grouping an array used to mean writing a reduce. Now it's one call:

JS
const posts = [
  { title: "Springs", category: "animation" },
  { title: "Flexbox", category: "css" },
  { title: "Grid", category: "css" },
];

const byCategory = Object.groupBy(posts, (post) => post.category);
// { animation: [...1 post], css: [...2 posts] }

There's also Map.groupBy if you want keys that aren't strings.

Array.prototype.at

Need the last item of an array? Skip the arr[arr.length - 1] dance:

JS
const steps = ["plan", "build", "ship"];
steps.at(-1); // "ship"
steps.at(-2); // "build"

Intl.RelativeTimeFormat

"3 days ago" and "in 2 hours" are surprisingly fiddly to get right in every language. The Intl API does it for you:

JS
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });

rtf.format(-1, "day");   // "yesterday"
rtf.format(3, "week");   // "in 3 weeks"
rtf.format(-2, "hour");  // "2 hours ago"

Swap "en" for any locale and the output is translated and grammatically correct.

AbortController, beyond fetch

Most people know AbortController for cancelling requests. Fewer know it can remove event listeners too, several at once:

JS
const controller = new AbortController();
const { signal } = controller;

window.addEventListener("resize", onResize, { signal });
window.addEventListener("scroll", onScroll, { signal });
document.addEventListener("keydown", onKey, { signal });

// Later: remove all three listeners in one go
controller.abort();

No more keeping references to every handler just so you can remove it later.

Check before you ship

All five are supported in current versions of Chrome, Firefox, Safari and Node.js, but Object.groupBy arrived more recently than the others. If you support older browsers, check your analytics, or add a small polyfill.

The best dependency is the one you don't have to install.

Want to know when I publish something new?

I send a short email when there's a new article or project, usually a couple of times a month. No spam, and you can unsubscribe whenever you like.