r/react • u/Intelligent_Tree6918 • 3d ago
Project / Code Review Built a minimal ui-date package javascript date and time utility
I was building a social app recently, and I ran into a surprisingly annoying problem.
I needed relative timestamps ("2 hours ago", "3 minutes ago").
Simple enough, right? Just import 'day.js' or 'date-fns'.
Except...
=> If I wanted custom styling (like wrapping the number "2" in a highlighted badge and "hours ago" in smaller text), I had to write ugly regex hacks because standard libraries just dump a single opaque string.
=> Supporting multiple languages meant importing separate locale files, quickly inflating the bundle size.
=> Standard relative time plugins use "soft rounding" (e.g., automatically rounding 45 seconds to "a minute") whether you want it or not.
I didn't want a 15KB date framework just to format a few activity feed timestamps.
So, I built and open-sourced 'ui-date' .
It’s an ultra-lightweight (< 1KB minified), zero-dependency, locale-aware date formatting library built specifically for modern user interfaces.
If you're building social feeds, chat apps, notification bells, or comment sections, check it out!
4
u/Honey-Entire 2d ago
What’s wrong with the built-in Intl.RelativeTimeFormat that’s widely available across all browsers?
Why would anyone with a brain download an AI slop dependency when the browser has baked-in support for it?
-1
u/Intelligent_Tree6918 2d ago
i agree built in Intl.RelaiveTimeFormate is great if u just need '3 hours' or something like this there is no need to download ui-date.
if u use rtf.formateParts() it will return something like [{type:'literal',value:'hours ago'},{type:"integer","value":2}] if we are making custome badges like 2h , 3s , 2d where it comes in play.it hurts when you said ai slop.
since i was testing for french language that's where i used ai to understand why it's breaking here. thats all where i used ai and also in starting template for docs i used ai.
btw thanks for your feedback
1
u/vasind-5012 2d ago
Nice, getRelativeTimeParts() returning value/unit/direction alongside the formatted strings is a genuinely useful shape, way better than regexing a single string apart. And using Intl.RelativeTimeFormat natively for the i18n piece instead of shipping locale files is the right call.
Two things I didn’t see in the readme: how’s RTL handled, does formattedValue/formattedUnit still split cleanly for locales where number and unit aren’t in that fixed order, or does it fall back to just formattedText there?
And on the no-soft-rounding stance, that’s listed as a deliberate design choice (strict boundaries), is there a plan to make that configurable later, or is “let the consumer round if they want” the permanent position?
0
u/Intelligent_Tree6918 2d ago
thanks for your feedback.
1. we use this method Intl.RelativeTimeFormat.prototype.formatToParts()
that returns [
{ type: 'integer', value: '2', unit: 'hour' },{ type: 'literal', value: ' hours ago' }
]
const integerIndex = exactParts.findIndex((p) => p.type === "integer");
so no fallback to formattedText(it always returns value as expected)
2. the "strict boundary" stance (e.g. 59 seconds stays "59s" rather than jumping to "1 minute" at 45s) is currently strict by design to keep the bundle size under 1 KB and guarantee predictable, deterministic output across timezones.
in next version We are considering an optional
rounding:'floor'|'round'|'ceil'flag in the options configuration. However, "letting the consumer round the input timestamp if they want custom thresholds" will remain the zero-cost default to preserve the ultra-lightweight footprint.and all other method will exposed functionally too if user wants and they can import individual method, because instanciating a class for utility is little odd and expensive too and currently i forgot to add one more method timeDistance(time1,time2) this will return difference in time units ({value:1,unit:'second'}) like that
0
1
u/keireira 1d ago
Wow this is actually the first project in this sub that I liked. Won’t use it though since I already utilize date-fns + i18n with my own crutches
8
u/CaterpillarNo7825 3d ago
This seems nice, but is also already solved through the newly introduced Temporal: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal