{"id":12605,"library":"vue-timer-hook","title":"Vue Timer Hook","description":"Vue Timer Hook is a Vue 3 composition API library providing reactive hooks for common time-based functionalities within components. It offers `useTimer` for countdowns, `useStopwatch` for tracking elapsed time, and `useTime` for continuously retrieving the current time. Currently at version 1.0.86, the library demonstrates a positive version release cadence, with the last publish occurring 3 months ago, indicating active maintenance. Its primary benefit lies in simplifying time-related state management in Vue components, abstracting away complex `setInterval` and `clearInterval` logic, and providing a clean, reactive interface. It is purpose-built for the Vue 3 ecosystem and the Composition API, making it a direct fit for modern Vue projects.","status":"active","version":"1.0.86","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","vue","vue3","timer","hook","typescript"],"install":[{"cmd":"npm install vue-timer-hook","lang":"bash","label":"npm"},{"cmd":"yarn add vue-timer-hook","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-timer-hook","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for Vue 3 Composition API functionality.","package":"vue","optional":false}],"imports":[{"note":"This library is ESM-only and specifically designed for Vue 3's Composition API. CommonJS `require` syntax will not work.","wrong":"const useTimer = require('vue-timer-hook')","symbol":"useTimer","correct":"import { useTimer } from 'vue-timer-hook'"},{"note":"`useStopwatch` is a named export, not a default export. Ensure you use curly braces for destructuring.","wrong":"import useStopwatch from 'vue-timer-hook'","symbol":"useStopwatch","correct":"import { useStopwatch } from 'vue-timer-hook'"},{"note":"Import directly from the package name `vue-timer-hook`, not a relative path.","wrong":"import { useTime } from './vue-timer-hook'","symbol":"useTime","correct":"import { useTime } from 'vue-timer-hook'"}],"quickstart":{"code":"<template>\n  <div>\n    <h1>Vue Timer Hook Demo</h1>\n    <p>Countdown Timer:</p>\n    <div>\n      <span>{{ timer.days }}</span>:<span>{{ timer.hours }}</span>:<span>{{ timer.minutes }}</span>:<span>{{ timer.seconds }}</span>\n    </div>\n    <p>{{ timer.isRunning.value ? 'Running' : 'Not running' }}</p>\n    <button @click=\"timer.start()\">Start</button>\n    <button @click=\"timer.pause()\">Pause</button>\n    <button @click=\"timer.resume()\">Resume</button>\n    <button @click=\"restartFive()\">Restart to 5 minutes</button>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  import { watchEffect, onMounted, ref } from 'vue'\n  import { useTimer } from 'vue-timer-hook'\n\n  // Set an initial 10-minute timer\n  const initialTime = new Date()\n  initialTime.setSeconds(initialTime.getSeconds() + 600) // 10 minutes\n\n  const timer = useTimer(initialTime, { autoStart: true })\n\n  const restartFive = () => {\n    // Restarts to a new 5-minute timer\n    const newTime = new Date()\n    newTime.setSeconds(newTime.getSeconds() + 300)\n    timer.restart(newTime)\n  }\n\n  onMounted(() => {\n    // Watch for the timer to expire\n    watchEffect(() => {\n      if (timer.isExpired.value) {\n        console.log('Timer has expired!')\n        // You could trigger an action here, e.g., show a message\n      }\n    })\n  })\n</script>","lang":"typescript","description":"This quickstart demonstrates how to create a 10-minute countdown timer using `useTimer`, control it with start, pause, resume, and restart functions, and react to its expiration. It also highlights accessing reactive properties with `.value`."},"warnings":[{"fix":"Ensure your project is using Vue 3 and that components are structured with the Composition API (e.g., `<script setup>`).","message":"`vue-timer-hook` is exclusively designed for Vue 3's Composition API. It is not compatible with Vue 2 or the Options API without significant adaptation, and attempting to use it will lead to runtime errors due to missing Vue 3 specific APIs.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always append `.value` when reading or writing to reactive properties returned by the hooks, for example: `if (timer.isExpired.value) { /* ... */ }`.","message":"When accessing reactive state properties like `timer.isExpired`, `stopwatch.isRunning`, or any time value (e.g., `timer.seconds`), remember they are Vue `ref` objects and require `.value` to access their current primitive state (e.g., `timer.isExpired.value`, `timer.seconds.value`). Direct access without `.value` will return the ref object itself, potentially leading to incorrect logic or rendering issues.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always initialize `useTimer` with a valid `new Date()` object, ensuring its seconds/minutes are correctly set, or a valid numeric timestamp. For example: `new Date(Date.now() + 60000)` for one minute.","message":"The `expiryTimestamp` parameter for `useTimer` expects a JavaScript `Date` object or a numeric timestamp (milliseconds since epoch). Providing other types (e.g., a plain number for seconds) or an invalid `Date` object will result in the timer behaving unexpectedly or not starting at all.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When calling `timer.restart()`, pass a newly created `Date` object, e.g., `timer.restart(new Date(Date.now() + 5 * 60 * 1000))`. For `useStopwatch.restart()`, simply call `stopwatch.restart()` without arguments to reset it.","message":"The `restart` method for `useTimer` requires a *new* `Date` object to define the new expiry timestamp. Reusing and mutating the *same* `Date` object reference passed initially might not trigger reactivity as expected; always create a fresh `Date` for subsequent `restart` calls.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use a unique `:key` prop on components using these hooks when they are part of a `v-for` loop or conditionally rendered with `v-if` to ensure proper component lifecycle and re-initialization. For example: `<MyTimerComponent v-if=\"showTimer\" :key=\"uniqueId\" />`.","message":"When conditionally rendering components that use `vue-timer-hook` (e.g., with `v-if`), Vue might reuse component instances without re-running setup logic if a `key` attribute is not provided, leading to timers not initializing or resetting correctly.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Access reactive properties using `.value`, for instance: `timer.isRunning.value` or `timer.seconds.value`.","cause":"Attempting to access a reactive property (e.g., `isRunning`, `isExpired`, `seconds`) from a `vue-timer-hook` return value without appending `.value`.","error":"TypeError: Cannot read properties of undefined (reading 'value')"},{"fix":"Ensure your Vue component uses `<script setup lang='ts'>` and your project is configured for Vue 3.","cause":"The component where the hook is used is not set up for Vue 3 Composition API (e.g., missing `<script setup>`), or the project is using Vue 2.","error":"Syntax Error: [plugin:vite:vue] `useTimer` is not defined"},{"fix":"Ensure `useTimer` is initialized with a properly constructed `new Date()` object, for example: `const time = new Date(); time.setSeconds(time.getSeconds() + 300);`.","cause":"The `expiryTimestamp` argument provided to `useTimer` is not a valid JavaScript `Date` object or a numeric timestamp.","error":"Uncaught TypeError: time.setSeconds is not a function"}],"ecosystem":"npm"}