Countdown
Animated countdown to an upcoming event or meeting deadline.
Use Countdown when you need to show time remaining until a scheduled event, meeting start, or acceptance deadline. Numbers animate with NumberFlow as the timer ticks down.
Two variants ship today:
compact—DD:HH:MM:SSinline timer, matching the NumberFlow countdown example.card— labeled units with event title, date badge, and full datetime footer.
On Cal Events public pages, use the compact timer in the main column beside the cover art — same layout as MeetupEventLayout.
import { Countdown } from "@coss/ui/shared/countdown";Examples
packages/features/cal-events · MeetupEventLayout + Countdown

Product launch keynote
NOV
9
Monday, November 9
2:30 PM
Starts in
San Francisco, CA
apps/web/modules/videos · meeting-not-started + Countdown
This meeting has not started yet
Weekly product syncMonday, October 26, 2026 at 11:03 PM
variant="compact" · DD:HH:MM:SS
variant="card" · labeled units with event chrome
Upcoming event
Product launch keynote
Months11
Weeks11
Days33
Hours1616
Minutes1111
Seconds4444
Monday, December 7, 2026 at 2:30 PM
variant="card" · minUnits="hours"
Next meeting
Team standup
Days22
Hours1616
Minutes1111
Seconds4444
Thursday, October 29, 2026 at 2:30 PM
<ResponseCard
icon={<ClockIcon />}
title={t("this_meeting_has_not_started_yet")}
description={/* booking title + scheduled time */}
action={<Button size="lg">{t("view_booking")}</Button>}
>
<div className="flex w-full flex-col items-center gap-2 rounded-xl border border-border bg-muted/40 px-4 py-3">
<p className={countdownStartsInLabelClassName}>Starts in</p>
<Countdown target={booking.startTime} variant="compact" className="text-2xl sm:text-3xl" />
</div>
</ResponseCard><div className="flex flex-col gap-2 rounded-xl border border-border bg-muted/40 p-4">
<p className={countdownStartsInLabelClassName}>Starts in</p>
<Countdown target={eventStartTime} variant="compact" />
</div><Countdown target={meetingStartTime} variant="compact" /><Countdown
target={meetingStartTime}
variant="card"
title={eventTitle}
eyebrow="Next meeting"
minUnits="hours"
/>API
| Prop | Type | Notes |
|---|---|---|
target | Date | string | number | Required event deadline. |
variant | "compact" | "card" | Defaults to "compact". |
title | ReactNode | Card heading. Ignored in compact mode. |
eyebrow | ReactNode | Card kicker above the title. Defaults to "Next event". |
className | string | Merged onto the outer element. |
hideZeroUnits | boolean | Card only. Hides leading zero units on first render. Defaults to true. |
minUnits | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds" | Card only. Always show this unit and every smaller one. |
invalidTargetMessage | ReactNode | Shown when target is invalid. Renders nothing when omitted. |
Hook
For custom layouts, derive countdown state with useCountdown:
import { useCountdown } from "@coss/ui/hooks/use-countdown";Call sites
| File | Notes |
|---|---|
apps/web/modules/videos/views/videos-meeting-not-started-single-view.tsx | Meeting not started — planned countdown in ResponseCard |
packages/features/cal-events/components/event-page/layouts/layout-meetup.tsx | Cal Events meetup page layout — planned countdown placement |
Example URLs
Not exhaustive — a few places this pattern fits in product once adopted.
| Path | Notes |
|---|---|
/<eventSlug> | Cal Events public page (when slug resolves to an event) |
/connect-and-join?token=<token> | Instant meeting acceptance window |
/video/meeting-not-started/<uid> | Meeting has not started yet |
Source
On This Page