Overview
anywhen is a ~800b gzip date formatting library built entirely on the native Intl browser API. No locale files, no plugins, no config — just three functions that cover the most common date formatting needs.
The browser already knows how to format dates in 200+ languages. anywhen just makes that API pleasant to use.
import { anydate, anywhen, anyago, anywhere } from 'anywhen'
anydate(date, 'en') // "Feb 5, 2016"
anywhen(date, 'en') // "yesterday, 2:35 PM"
anyago(date, 'en') // "3 hours ago"Install
npm install anywhen
# or
pnpm add anywhen
# or
yarn add anywhenanydate()
Always returns an absolute date string. Pass any Intl.DateTimeFormat options to control the format.
anydate(input, locale, options?)
anydate(date, 'en')
// "Feb 5, 2016"
anydate(date, 'en', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })
// "Friday, February 5, 2016"
anydate(date, 'en', { hour: '2-digit', minute: '2-digit' })
// "2:35 PM"
anydate(date, 'en', { month: 'long', year: 'numeric' })
// "February 2016"inputDate | number | stringThe date to format. Accepts a Date object, unix timestamp in ms, or ISO string.
localestringAny valid BCP 47 locale tag — 'en', 'en-US', 'zh-TW', 'pt-BR'.
optionsIntl.DateTimeFormatOptionsdefault: { day, month, year }Any options accepted by Intl.DateTimeFormat. Defaults to a short date.
anywhen()
Smart context picker. Chooses the most readable format based on distance from now — covers past and future.
anywhen(input, locale, time?)
anywhen(date, 'en') // "just now"
anywhen(date, 'en') // "10 minutes ago"
anywhen(date, 'en') // "today, 2:35 PM"
anywhen(date, 'en') // "yesterday, 9:00 AM"
anywhen(date, 'en') // "Wednesday, 11:20 AM"
anywhen(date, 'en') // "Feb 5, 2016"
anywhen(date, 'en') // "in 2 weeks"
anywhen(date, 'en', false) // "yesterday" — no clockswitching logic
inputDate | number | stringThe date to format.
localestringAny valid BCP 47 locale tag.
timebooleandefault: trueWhether to include clock time in today/yesterday/weekday output. Pass false to omit.
anyago()
Always relative. Past and future. Never switches to an absolute date.
anyago(input, locale, numeric?)
anyago(date, 'en') // "3 hours ago"
anyago(date, 'en') // "yesterday"
anyago(date, 'en') // "in 2 weeks"
anyago(date, 'en', true) // "1 day ago" — numeric mode, no "yesterday"
anyago(date, 'en', true) // "1 week ago" — numeric mode, no "last week"inputDate | number | stringThe date to format.
localestringAny valid BCP 47 locale tag.
numericbooleandefault: falseForce numeric output — disables auto-phrases like 'yesterday' or 'last week'.
anywhere()
Returns a locale-bound instance — useful when formatting many dates in the same locale.
import { anywhere } from 'anywhen'
const t = anywhere('en')
t.anydate(date) // "Feb 5, 2016"
t.anywhen(date) // "yesterday, 2:35 PM"
t.anyago(date) // "3 hours ago"
t.anydate(date, { weekday: 'long', month: 'long',
day: 'numeric', year: 'numeric' }) // "Friday, February 5, 2016"Input types
All functions accept three input formats interchangeably.
// Date object
anydate(new Date(), 'en')
// Unix timestamp (milliseconds)
anydate(Date.now(), 'en')
anydate(1704499200000, 'en')
// ISO string
anydate('2016-02-05T14:00:00Z', 'en')
anydate('2016-02-05', 'en')Locales
All output is in English in the examples above. Here's the same calls in a few other languages — no extra setup required.
anydate(date, 'de') // "5. Feb. 2016"
anydate(date, 'ja') // "2016年2月5日"
anydate(date, 'ar') // "٥ فبراير ٢٠١٦"
anydate(date, 'ru') // "5 февр. 2016 г."
anydate(date, 'fr') // "5 févr. 2016"
anydate(date, 'zh') // "2016年2月5日"
anyago(date, 'de') // "vor 3 Stunden"
anyago(date, 'fr') // "il y a 3 heures"
anyago(date, 'tr') // "3 saat önce"
anyago(date, 'ru') // "3 часа назад"
anyago(date, 'ar') // "منذ 3 ساعات"
anywhen(date, 'de') // "gestern, 14:35"
anywhen(date, 'ru') // "вчера, 14:35"
anywhen(date, 'fr') // "hier, 14:35"Pass any valid BCP 47 language tag — including regional variants like en-GB, zh-TW, or pt-BR.
Compatibility
anywhen uses Intl.RelativeTimeFormat and Intl.DateTimeFormat — both widely supported.
Limitations
A few things worth knowing before you ship:
Output depends on the runtime's Intl data
anywhen delegates all formatting to native Intl. Exact output — punctuation, spacing, abbreviated month names — may vary between Node versions, browsers, and OSes. Don't hardcode expected strings in tests; use pattern matching instead.
No custom format strings
anydate() accepts Intl.DateTimeFormat options, so you control the pieces. But if you need 'DD/MM/YYYY' with literal slashes — use a formatting library with explicit pattern strings instead.
anywhen cutoff is fixed at 7 days
The switch from weekday ('Wednesday, 11:20') to absolute date happens at 7 days and is not configurable. Need a custom cutoff? Use anyago() and anydate() directly.
Node.js < 13
Older Node versions shipped with small-icu — only the 'en' locale was guaranteed. Node 13+ includes full ICU. On older versions, install the full-icu package separately.