You're installing date-fns for 'X hours ago'. Intl.RelativeTimeFormat does it natively.
Most apps display relative timestamps — '3 minutes ago', 'last week'. Developers still reach for date-fns or moment for this. The Intl.RelativeTimeFormat API handles it natively, with full locale support and zero dependencies.

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.
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 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:
In most UIs, numeric: 'auto' is what you want. Saying "yesterday" is more natural than "1 day ago" and it costs nothing extra.
The API doesn't pick the unit for you — you pass 'hour' or 'week' explicitly. That means you need a helper that looks at the elapsed duration and decides which unit to use. Ten lines:
You adjust the thresholds to your app's conventions — some UIs show minutes up to 90, others switch to hours at 60. The formatter handles the phrasing; the thresholds handle the unit selection.
The formatter respects locale — the same code that prints "3 hours ago" in English prints "il y a 3 heures" in French, "vor 3 Stunden" in German, and "۳ ساعت پیش" in Persian, without any translation strings in your bundle.
Most date libraries ship locale data as separate imports or packages — kilobytes of JSON per language. Intl.RelativeTimeFormat uses the locale data already in the JavaScript engine. Nothing extra to load.
Intl.RelativeTimeFormat formats a pre-computed duration. It doesn't parse date strings, calculate diffs, or understand "last Monday." If you need date arithmetic — adding months, finding the start of a week, working with time zones — you still need a library or the upcoming Temporal API. But if you already have two timestamps and just want to display the difference as human text, Intl.RelativeTimeFormat is the right tool.
Intl.RelativeTimeFormat is Baseline 2020: Chrome 71 (2018), Firefox 65 (2019), Safari 14 (2020), Node.js 12. It's been in every major environment for years. No polyfill needed for any currently-supported browser.
Runs right in your browser — poke at it and watch the concept react live.
Think it clicked? Take the 9-question quiz →
Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.
Search your codebase for formatDistanceToNow, fromNow(), or any home-grown "X minutes ago" function. If the logic is "compute a diff, format it as human text," replace it with Intl.RelativeTimeFormat and a unit-picking helper. You get correct pluralization, locale-aware phrasing, and natural-language output like "yesterday" and "tomorrow" — with no added dependency and no locale bundle to manage.
Thanks for reading! Let's stay connected:
- ⭐ GitHub — follow me and star the projects: github.com/parsajiravand
- 💬 Discord — join the frontend best-practices community: discord.gg/d9KRhuAwQ
- 📸 Instagram — frontend best practices, daily: @bestpractice___
- 💼 LinkedIn — linkedin.com/in/parsa-jiravand
- ✉️ Email (work & contract inquiries): bestpractice2026@gmail.com
Originally published on dev.to