Pro
Relative time
A timestamp that reads as a distance from now ("3 minutes ago", "yesterday") and keeps itself current. It is a real time element with the exact moment in its dateTime and the full date as its title, in the reader's language.
pnpm dlx shadcn@latest add @caliper/relative-timeWhen to use
Use it for
- Feeds, comments, notifications and run histories, where recency matters more than the clock time.
- Lists of many rows: every instance on the page shares one 15-second clock.
Skip it when
- Records where the exact time is the fact (an audit trail, an invoice date); show the date.
- Deadlines; say the date, and use the countdown for the last stretch.
Decisions
Why it is built this way, so you know what to keep when you change your copy.
Behaviour
- One clock for the page
- Every label subscribes to a single timer that runs only while the tab is visible, so a hundred rows are one interval.
- Server renders the date
- The server cannot know the reader's clock, so it prints the plain date and the relative label takes over after hydration.
Installation
pnpm dlx shadcn@latest add @caliper/relative-time
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. Pro installs with your access token, set up once per project. See Pro access. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage
Import it from your copy of the source. The example behind the preview comes with the source. It is built from RelativeTime and formatRelative.
import { RelativeTime, formatRelative } from "@/components/ui/relative-time"
The worked example comes with Pro
The 47-line example behind the preview opens here, ready to copy.
- 576 Pro parts, blocks and page templates, all with source
- $199 once, with a year of updates. What you have stays yours
- A full refund within 14 days if it is not for you
API reference
RelativeTime
component
Also accepts the native props of its root element and a ref.
formatRelative
component
No props of its own; it accepts the native props of its root element.
Accessibility
It is built on native elements, so roles and focus come from the browser.
No custom key handling; Tab and the native activation keys do the work.
Motion
Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.