Skip to content

shadcn.io is an independent project built on shadcn/ui

Docs

Free

useCountdown for React

A number that ticks on an interval, with start, stop and reset. For React, when a launch clock, a quiz timer or a short wait should count on its own.

useCountdown keeps a number and three controls: startCountdown, stopCountdown, and resetCountdown.

Use it for a sale clock, a session timeout, or a quiz timer. For a count you change only with buttons, use useCounter. In React the interval stays off until startCountdown runs, so the first paint is just countStart.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

useCountdown anatomy: useCountdown(), count, startCountdown, stopCountdown, resetCountdown

Usage

import { useCountdown } from "@/hooks/use-countdown";
const [count, { startCountdown, stopCountdown, resetCountdown }] =
  useCountdown({ countStart: 30 });

countStop defaults to 0, intervalMs to 1000, and isIncrement to false, so it counts down once a second until it hits the stop value.

FAQ

Can the countdown count up?

Yes. Pass isIncrement: true and the tick adds one instead of subtracting one. It still stops only when count equals countStop. If you count up from a start that is already above countStop, the numbers never match and the timer keeps going. Set countStop to the value where it should halt.

Does the countdown stop at zero by itself?

It stops when the count equals countStop, which defaults to 0. The comparison runs at the start of a tick, so the number lands on the stop value and sits there. One interval later the timer clears itself without changing the number again. Pass a different countStop when the end should not be zero.

How do I change the countdown speed?

Pass intervalMs. The default is 1000, so one tick per second. The interval is created only while the countdown is running, and it is rebuilt when intervalMs changes. A smaller number ticks faster. The step is still one. This option does not change how much is added or subtracted.

Can I pause and resume the countdown?

Yes. stopCountdown sets the running flag to false and leaves the current number in place. startCountdown sets that flag back to true, and the next ticks continue from the number you already have. resetCountdown stops and sets the number back to countStart. None of the three change the options.

What if I start when the count already equals the stop value?

The next tick sees that they are equal, turns the timer off, and does not add or subtract. startCountdown itself only sets a flag. It does not look at the numbers. So a countdown that begins on countStop waits one intervalMs and then stops, still showing that same number.

Is the countdown safe on the server?

Yes. The hook only uses state and effects. No interval is created until startCountdown runs in the browser. The first render is countStart on the server and the client. Changing countStart later does not move the current number. It only changes what resetCountdown writes back.

API Reference

Parameters

ParameterType
optionsCountdownOptions

Where it starts and stops, how fast, and which way.

options.countStartnumber

The count it starts from, and goes back to on reset.

options.countStop?number

The count it stops at.

Default
0
options.intervalMs?number

Milliseconds between steps.

Default
1000
options.isIncrement?boolean

Counts up instead of down.

Default
false

Returns

ValueType
[0] countnumber

The current count.

[1] controllersCountdownControllers

Functions that start, stop and reset it. Stable across renders.

controllers.resetCountdown() => void

Stops the countdown and puts the count back to countStart.

Type
() => void
controllers.startCountdown() => void

Starts (or resumes) counting from the current count.

Type
() => void
controllers.stopCountdown() => void

Pauses the countdown, keeping the current count.

Type
() => void