When a comment timestamp reads "3 hours ago" instead of a raw ISO string, users stay oriented without thinking about it. Most teams reach for date-fns/formatDistanceToNow or moment().fromNow() to get there. Both pull in a full library for something the browser can do natively — and has been able to do since 2020.
The API
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
rtf.format(-3, 'hour'); // "3 hours ago"
rtf.format(1, 'day'); // "tomorrow"
rtf.format(-1, 'day'); // "yesterday"
rtf.format(-2, 'week'); // "2 weeks ago"
rtf.format(3, 'month'); // "in 3 months"
Two arguments: a number (negative = past, positive = future) and a unit string. The constructor takes a locale identifier and an options object. That's the whole surface area.
The numeric: 'auto' option
The second constructor argument controls whether you get "1 day ago" or "yesterday". With numeric: 'always' (the default), every value is formatted as a number. With numeric: 'auto', the formatter substitutes natural language when it's available for that locale:
const always = new Intl.RelativeTimeFormat('en', { numeric: 'always' });
const auto = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
always.format(-1, 'day'); // "1 day ago"
auto.format(-1, 'day'); // "yesterday"
always.format(0, 'day');