npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shak-hooks/vue

v0.0.2

Published

Vue composables for Shak Hooks

Downloads

194

Readme

@shak-hooks/vue

Vue 3 composables for Shak Hooks.

Install

npm i @shak-hooks/vue

Requirements

  • Vue >=3

Usage

<script setup lang="ts">
import { useCounter } from "@shak-hooks/vue";

const [count, { inc, dec }] = useCounter(0);
</script>

<template>
  <button @click="dec()">-</button>
  <span>{{ count }}</span>
  <button @click="inc()">+</button>
</template>

Testing

Run only the Vue composable tests from the repo root:

pnpm test:vue

Hooks

  • useBattery
  • useClickAway
  • useContinuousRetry
  • useCopyToClipboard
  • useCountdown
  • useCounter
  • useDebounce
  • useDefault
  • useDocumentTitle
  • useEventListener
  • useFavicon
  • useFetch
  • useGeolocation
  • useHistoryState
  • useHover
  • useIdle
  • useIntersectionObserver
  • useInterval
  • useIntervalWhen
  • useIsClient
  • useIsFirstRender
  • useKeyPress
  • useList
  • useLocalStorage
  • useLockBodyScroll
  • useLogger
  • useLongPress
  • useMap
  • useMeasure
  • useMediaQuery
  • useMouse
  • useNetworkState
  • useObjectState
  • useOrientation
  • usePageLeave
  • usePreferredLanguage
  • usePrevious
  • useQueue
  • useRandomInterval
  • useRenderCount
  • useRenderInfo
  • useScript
  • useSessionStorage
  • useSet
  • useThrottle
  • useTimeout
  • useToggle
  • useVisibilityChange
  • useWindowScroll
  • useWindowSize

API

useBattery

Tracks the Battery Status API (when supported).

const { level, charging } = useBattery();

useClickAway

Calls a handler when a click happens outside the target element ref.

const el = ref<HTMLElement | null>(null);
useClickAway(el, () => (open.value = false));

useContinuousRetry

Retries an async/sync callback at a fixed interval until it returns true or hits maxRetries.

const done = useContinuousRetry(() => Boolean(localStorage.getItem("ready")), 200, { maxRetries: 10 });

useCopyToClipboard

Copies text to the clipboard.

const { value, copy, error } = useCopyToClipboard();
await copy("hello");

useCountdown

Countdown timer with controls.

const { count, start, stop, reset } = useCountdown(10);

useCounter

Counter with optional min/max and helpers.

const [count, { inc, dec, set, reset }] = useCounter(0, { min: 0, max: 10 });

useDebounce

Debounces a value/ref and returns a Ref of the debounced value.

const debounced = useDebounce(search, 250);

useDefault

Returns a computed default when the internal state is null/undefined.

const { value, state } = useDefault<string | null>(null, "fallback");

useDocumentTitle

Sets document.title (with optional restore on unmount).

useDocumentTitle(() => `Page: ${route.name}`, { restoreOnUnmount: true });

useEventListener

Adds an event listener to window (default) or a provided target/ref target. Returns a stop() cleanup function.

const stop = useEventListener("keydown", (e) => console.log(e));
stop();

useFavicon

Sets the favicon URL.

useFavicon("/favicon.ico");

useFetch

Reactive fetch helper with data, error, loading, execute, abort.

const { data, loading, error } = useFetch<{ ok: boolean }>("/api/health");

useGeolocation

Tracks the Geolocation API (when supported).

const { coords, locatedAt, error } = useGeolocation();

useHistoryState

Stores state in history.state under a key.

const { state, setHistoryState } = useHistoryState({ tab: "home" }, "page-state");

useHover

Tracks hover state for an element ref.

const el = ref<HTMLElement | null>(null);
const hovered = useHover(el);

useIdle

Becomes true after ms of no activity; resets on user activity.

const idle = useIdle(60_000);

useIntersectionObserver

IntersectionObserver wrapper.

const el = ref<HTMLElement | null>(null);
const entry = useIntersectionObserver(el, { threshold: 0.1 });

useInterval

Interval runner with a reactive delay (pass null to pause).

useInterval(() => tick.value++, delay);

useIntervalWhen

Interval runner gated by a boolean condition.

useIntervalWhen(() => tick.value++, 1000, enabled, true);

useIsClient

Returns true after the component mounts.

const isClient = useIsClient();

useIsFirstRender

Returns true on the first render, then false.

const isFirst = useIsFirstRender();

useKeyPress

Tracks whether a specific key is currently pressed.

const pressed = useKeyPress("Escape");

useList

List state with helper actions.

const [list, actions] = useList<string>(["a"]);
actions.push("b");

useLocalStorage

LocalStorage-backed state.

const [value, setValue] = useLocalStorage("theme", "light");

useLockBodyScroll

Locks body scroll (sets body.style.overflow = "hidden").

useLockBodyScroll(true);

useLogger

Console logging lifecycle helper (mount/update/unmount).

useLogger("MyComponent", { debug: true });

useLongPress

Long-press detection for mouse/touch with callbacks.

const bind = useLongPress(() => console.log("long press"), { delay: 500 });

useMap

Map state with helper actions.

const [map, actions] = useMap<string, number>([["a", 1]]);
actions.set("b", 2);

useMeasure

Element measurement via ResizeObserver.

const [el, rect] = useMeasure();

useMediaQuery

Tracks a media query match.

const isWide = useMediaQuery("(min-width: 768px)");

useMouse

Tracks mouse position.

const { x, y } = useMouse();

useNetworkState

Tracks network status (online/offline + connection info where available).

const state = useNetworkState();

useObjectState

Object state with merge update.

const { state, update } = useObjectState({ a: 1, b: 2 });
update({ b: 3 });

useOrientation

Tracks device orientation events (where available).

const state = useOrientation();

usePageLeave

Calls a callback when the mouse leaves the page viewport.

usePageLeave(() => console.log("left page"));

usePreferredLanguage

Returns the user’s preferred language (when available).

const lang = usePreferredLanguage();

usePrevious

Returns the previous value of a ref/getter.

const prev = usePrevious(() => value.value);

useQueue

Queue state with helper actions.

const [queue, actions] = useQueue<number>([1, 2]);
actions.add(3);

useRandomInterval

Runs a callback at random intervals between minDelay and maxDelay.

useRandomInterval(() => console.log("tick"), 500, 1500);

useRenderCount

Returns the current render count.

const renders = useRenderCount();

useRenderInfo

Logs render timing information to the console.

useRenderInfo("MyComponent");

useScript

Loads an external script and returns its status ref.

const status = useScript("https://example.com/sdk.js");

useSessionStorage

SessionStorage-backed state.

const [value, setValue] = useSessionStorage("draft", "");

useSet

Set state with helper actions.

const { set, add, remove, has, toggle, reset } = useSet<string>(["a"]);
add("b");

useThrottle

Throttles a rapidly changing value/ref.

const throttled = useThrottle(value, 250);

useTimeout

Runs a callback after a reactive delay (pass null to disable).

useTimeout(() => console.log("done"), delay);

useToggle

Boolean toggle with helper actions.

const [on, actions] = useToggle(false);
actions.toggle();

useVisibilityChange

Tracks whether the document is visible.

const visible = useVisibilityChange();

useWindowScroll

Tracks window scroll position.

const { x, y } = useWindowScroll();

useWindowSize

Tracks window size.

const { width, height } = useWindowSize();