timeago-react
A tiny React component that renders live, auto-updating relative timestamps like "3 hours ago".
Repository Health
Technical Analysis
timeago-react is a small React wrapper around the timeago.js formatting engine that turns a date, timestamp, or datetime string into a human-friendly relative-time statement such as “3 hours ago” or “1 day ago”. Rather than rendering a static string once, the <TimeAgo> component keeps itself in sync: it schedules its own re-render interval (an hour-old timestamp re-checks roughly every hour rather than every second), and cleans up that interval automatically on unmount or when the underlying date changes.
The component is deliberately thin — a single class component that delegates all formatting and interval logic to timeago.js, exposing only the props needed to control that behavior: the date to format, whether to keep it live, a locale, and pass-through formatting options. It supports the full range of timeago.js locales (importing and registering the ones you need), works across a very wide span of React versions declared in its peer dependency (0.14 through 19), and ships both CommonJS and ESM builds.
What You Get
- A
<TimeAgo>component accepting adatetimeas a Date instance, timestamp, or date string - Automatic live re-rendering on an efficiency-aware interval (checks less often as the elapsed time grows)
- Built-in cleanup of timers on unmount and on prop updates, preventing leaked intervals
- Locale support for every language timeago.js ships, registered on demand via
timeago.register - A
live={false}mode for a one-time static render with no interval at all - Pass-through of standard HTML
<time>element props (className, style, and other attributes)
Common Use Cases
- Showing “posted X ago” timestamps on comments, activity feeds, or notifications
- Displaying last-updated or last-seen indicators in dashboards and admin panels
- Rendering localized relative dates in multi-language products without hand-rolling date math
- Replacing a static formatted date with a live-updating one in chat or messaging UIs
Under The Hood
Architecture
The library is a single-purpose wrapper: packages/timeago-react/src/timeago-react.tsx defines one class component, TimeAgo extends React.PureComponent, that holds a ref to the underlying <time> DOM node and delegates all real work to timeago.js’s format, render, and cancel functions. componentDidMount and componentDidUpdate both call a shared renderTimeAgo() that first cancels any existing interval on the DOM node, then re-establishes live rendering unless live is explicitly false; componentWillUnmount cancels the interval to avoid leaks. There is no internal layering beyond this because the component’s entire job is to bridge React’s lifecycle to timeago.js’s imperative DOM-based API — a legitimately thin architecture for a legitimately narrow problem, published from an npm-workspaces monorepo that also contains a demo app.
Tech Stack
Written in TypeScript and built twice via tsc — once targeting CommonJS and once targeting ESNext — with a small postbuild.js script finishing packaging; shx handles cross-platform file removal between builds. The only runtime dependency is timeago.js (^4.0.0); React itself is a peer dependency spanning ^0.14.0 through ^19.0.0, kept extremely permissive since the component only touches a handful of stable lifecycle methods and React.PureComponent. Linting runs through ESLint 9’s flat config with typescript-eslint and eslint-plugin-react, formatting through Prettier, and commit messages are enforced with commitlint plus a Husky pre-commit hook.
Code Quality
Tests live in packages/timeago-react/__tests__/timeago-react.test.tsx and run under Vitest with @testing-library/react and jsdom, covering timestamp input, Date instance input, formatted date-string input, locale switching, custom className, and the opts.relativeDate option — a reasonably thorough surface for a component this small. Coverage reporting is wired via @vitest/coverage-v8. The component’s public props are typed through a documented TimeAgoProps interface, though several @ts-ignore comments are used deliberately around the React.ComponentProps/HTMLProps extensions to keep type compatibility working across the very wide supported React version range. No dedicated error-handling paths exist beyond timeago.js’s own formatting, which is appropriate given the component’s narrow scope.
API Design
The public API is a single required prop (datetime), three optional behavior props (live, locale, opts), and otherwise standard HTML <time> attributes passed straight through — getting a live relative timestamp on screen is one import and one JSX tag. The one piece of friction, documented directly in the README, is that any locale beyond the two bundled by default (en, zh_CN) must be manually imported from timeago.js/lib/lang/<locale> and registered with timeago.register() before use.