A simple React hook for creating countdown timers to any target date or time.
npm install @danielsledz/react-countdown-hook
# or
yarn add @danielsledz/react-countdown-hook
# or
pnpm add @danielsledz/react-countdown-hook
import { useCountdown } from "@danielsledz/react-countdown-hook";
const MyComponent = () => {
const { timeLeft, isPaused, togglePause, error } = useCountdown(
"2025-12-31T23:59:59"
);
if (error) return <p>Error: {error}</p>;
return (
<div>
<p>
{timeLeft.direction} {timeLeft.days}d {timeLeft.hours}h{" "}
{timeLeft.minutes}m {timeLeft.seconds}s
</p>
<button onClick={togglePause}>{isPaused ? "Resume" : "Pause"}</button>
</div>
);
};
import { useCountdown } from "@danielsledz/react-countdown-hook";
const MyComponent = () => {
const targetDate = new Date("2025-12-31T23:59:59");
const { timeLeft, isPaused, togglePause, error } = useCountdown(targetDate);
if (error) return <p>Error: {error}</p>;
const formatTime = (time: number) => time.toString().padStart(2, "0");
return (
<div>
<h2>Countdown to New Year 2026</h2>
<div style={{ fontSize: "2rem", fontFamily: "monospace" }}>
{timeLeft.direction === "-" ? "Time remaining:" : "Time since:"}
<br />
{formatTime(timeLeft.days)}:{formatTime(timeLeft.hours)}:
{formatTime(timeLeft.minutes)}:{formatTime(timeLeft.seconds)}
</div>
<button onClick={togglePause}>
{isPaused ? "โถ๏ธ Resume" : "โธ๏ธ Pause"}
</button>
</div>
);
};
import { useCountdown } from "@danielsledz/react-countdown-hook";
const EventCountdown = () => {
const { timeLeft, isPaused, togglePause, error } = useCountdown(
"2025-06-15T18:00:00"
);
if (error) return <p>Error: {error}</p>;
const isEventPassed = timeLeft.direction === "+";
return (
<div>
<h3>Summer Conference 2025</h3>
{isEventPassed ? (
<p>Event has passed! It's been {timeLeft.days} days since the event.</p>
) : (
<div>
<p>Event starts in:</p>
<div>
{timeLeft.days} days, {timeLeft.hours} hours, {timeLeft.minutes}{" "}
minutes, {timeLeft.seconds} seconds
</div>
<button onClick={togglePause}>
{isPaused ? "Resume Countdown" : "Pause Countdown"}
</button>
</div>
)}
</div>
);
};
targetDate
: The date and time to count down to (string or Date object).
Name | Type | Description |
---|---|---|
timeLeft |
{ days, hours, minutes, seconds, direction } |
Remaining time and countdown direction (- = future, + = past) |
isPaused |
boolean |
Whether the countdown is paused |
togglePause |
() => void |
Function to toggle pause/resume |
error |
string | null |
Error message if invalid input |
interface TimeLeft {
days: number;
hours: number;
minutes: number;
seconds: number;
direction: string; // "-" for future, "+" for past
}
interface CountdownHook {
timeLeft: TimeLeft;
isPaused: boolean;
togglePause: () => void;
error: string | null;
}
If the target date is invalid (e.g., useCountdown("invalid-date")
), the error
field will contain an appropriate message.
const { error } = useCountdown("invalid-date");
if (error) {
console.log(error); // "Invalid target date."
}
The package includes comprehensive unit and integration tests using Vitest and React Testing Library.
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
The test suite covers:
- โ Basic countdown functionality
- โ Pause/resume functionality
- โ Error handling for invalid dates
- โ Time calculations accuracy
- โ Edge cases and boundary conditions
- โ Integration scenarios
- โ Memory leak prevention
# Install dependencies
npm install
# Build the package (CommonJS + ESM)
npm run build
# Build TypeScript declarations
npm run build:types
# Watch for changes during development
npm run dev
# Clean build directory
npm run clean
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
The build process generates:
dist/index.js
- CommonJS bundledist/index.esm.js
- ES Module bundledist/index.d.ts
- TypeScript declarations
MIT ยฉ 2025 Daniel ลledลบ
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Clone your fork
- Install dependencies:
npm install
- Make your changes
- Add tests for new functionality
- Run tests:
npm test
- Build the package:
npm run build
- Submit a pull request