← All @molecule/* packages · App templates

@molecule/app-countdown-react

Feature · countdown · App (browser) · v1.0.1 · Apache-2.0

useCountdown hook + Countdown component for time-to-event displays

npm install @molecule/app-countdown-react

npm · Source on GitHub

How it works

@molecule/app-countdown-react is a ready-made countdown feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.

import { Countdown } from '@molecule/app-countdown-react'

// Compact default: "3d 4h 12m 5s"
<Countdown target="2026-12-31T23:59:59Z" expired={<span>Sale ended!</span>} />

// Colon format: "03:04:12:05"
<Countdown target={new Date('2026-12-31')} format="colon" />

// Long format: "3 days 4 hours 12 minutes 5 seconds"
<Countdown target={Date.now() + 3_600_000} format="long" />

Works with: @molecule/app-react, @molecule/app-ui, @molecule/app-ui-react

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Time-remaining countdown.

Exports:

  • useCountdown(target, tickMs?) — live state hook.
  • <Countdown> — display component with compact/long/colon formats and custom render.

Quick Start

import { Countdown } from '@molecule/app-countdown-react'

// Compact default: "3d 4h 12m 5s"
<Countdown target="2026-12-31T23:59:59Z" expired={<span>Sale ended!</span>} />

// Colon format: "03:04:12:05"
<Countdown target={new Date('2026-12-31')} format="colon" />

// Long format: "3 days 4 hours 12 minutes 5 seconds"
<Countdown target={Date.now() + 3_600_000} format="long" />

Type

feature

Installation

npm install @molecule/app-countdown-react @molecule/app-react @molecule/app-ui @molecule/app-ui-react react
npm install -D @types/react

API

Interfaces

CountdownProps

Props for {@link Countdown}.

interface CountdownProps {
  /** Target date / ISO string / epoch ms. */
  target: Date | string | number
  /** Display format. Defaults to `'compact'`. */
  format?: 'compact' | 'long' | 'colon'
  /** Renderer override — receives the live state for full control. */
  render?: (state: ReturnType<typeof useCountdown>) => ReactNode
  /** Optional rendered when the timer expires. */
  expired?: ReactNode
  /** Extra classes. */
  className?: string
}

CountdownState

Snapshot of time remaining until a target date.

interface CountdownState {
  /** Days remaining. */
  days: number
  /** Hours (0-23) within current day. */
  hours: number
  /** Minutes (0-59) within current hour. */
  minutes: number
  /** Seconds (0-59) within current minute. */
  seconds: number
  /** Total milliseconds remaining (negative if past). */
  msRemaining: number
  /** True once `target` is in the past. */
  expired: boolean
}

Functions

Countdown(props)

Live countdown display with three default formats:

  • 'compact'3d 4h 12m 5s (skips zero leading units)
  • 'long'3 days 4 hours 12 minutes 5 seconds
  • 'colon'03:04:12:05

Pass render for full control over markup.

function Countdown({
  target,
  format = 'compact',
  render,
  expired,
  className,
}: CountdownProps): ReactNode
  • props — Component props (see {@link CountdownProps}).

useCountdown(target, tickMs)

Live-updating countdown to a target date.

function useCountdown(target: string | number | Date, tickMs?: number): CountdownState
  • target — Date / ISO string / epoch ms.
  • tickMs — Refresh interval. Defaults to 1000.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-react ^1.0.1
  • @molecule/app-ui ^1.0.1
  • @molecule/app-ui-react ^1.0.1
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-react
  • @molecule/app-ui
  • @molecule/app-ui-react
  • react

The built-in 'compact' and 'long' formats hardcode English unit labels and pluralization ("3d 4h", "3 days 4 hours") — there is no locale bond. For localized apps use the render prop with useCountdown state and compose translated units via t() (or Intl.RelativeTimeFormat). expired only swaps the rendering once the target passes — schedule side effects (redirects, refetches) from useCountdown().expired in an effect, not from the component.