useCountDown

High-precision React hook for managing synchronized countdown timers with manual lifecycle controls and drift-correction.

Note

This hook uses a reference timestamp approach rather than a simple counter. This prevents "time drift," ensuring the countdown stays accurate even if the browser's event loop is busy.

Tip

You can use the increment control to add "bonus time" to a game or session without resetting the entire countdown logic.

Installation

bash

Description

The useCountDown manages time remaining by comparing the current system clock against a target absolute timestamp. This approach eliminates cumulative time drift caused by setInterval execution delays, ensuring sub-second accuracy even during heavy main-thread activity or browser tab throttling.

The hook provides explicit lifecycle management via a status state and memoized control functions. It supports manual starting, pausing, resetting, and dynamic time increments, making it suitable for complex timing logic like game loops, persistent timers, or transaction expirations.

Parameters

NameTypeDescription
endTimenumberThe target Unix timestamp (ms) to count down to.
startOnMountbooleanWhether the timer starts automatically on component mount. Default: false.
options.intervalnumberFrequency of UI updates in milliseconds. Default: 1000.
options.onTick(time: number) => voidCallback triggered on every tick with the current remaining time.
options.onComplete() => voidCallback triggered once the remaining time reaches zero.

Return values

NameTypeDescription
countnumberThe current remaining time in milliseconds.
statusstringThe current status of the timer. Status types are 'start', 'running', 'paused', and 'completed'.
controls.start() => voidInitiates the countdown if status is 'start'
controls.pause() => voidPauses the timer and stores the remaining duration.
controls.resume() => voidResumes a paused timer by calculating a new end timestamp.
controls.reset() => voidClears the timer and reverts to the initial duration.
controls.increment(ms?: number) => voidAdds the specified milliseconds to the current countdown.

Demo

Countdown

Status: StartRemaining: 10s

Source code

tsx