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

hooknest

v1.2.2

Published

A lightweight collection of essential React custom hooks — useDebounce, useLocalStorage, useToggle, useOnClickOutside, usePrevious, useCopyToClipboard

Downloads

79

Readme

hooknest 🪝

A lightweight, zero-dependency collection of production-ready React custom hooks.

npm version license react peer


Why hooknest?

Stop copy-pasting the same hooks across every project. hooknest gives you a clean, consistent set of battle-tested React hooks for the patterns you reach for every day — debouncing, local storage sync, clipboard access, and more.

  • ✅ Zero dependencies (only React as a peer dep)
  • ✅ ES Module native
  • ✅ Tree-shakeable — import only what you use
  • ✅ Works with React 17, 18, and 19

Installation

npm install hooknest

Hooks

| Hook | Description | |---|---| | useDebounce | Debounce a rapidly changing value by a delay | | useLocalStorage | Persist and sync state with localStorage | | useToggle | Boolean toggle with a clean API | | useOnClickOutside | Fire a callback when clicking outside an element | | usePrevious | Track the previous value of any state or prop | | useCopyToClipboard | Copy text to clipboard with a copied status flag |


Usage

useDebounce

Delays updating a value until after a specified wait time. Perfect for search inputs, API calls, and resize handlers.

import { useDebounce } from "hooknest";

function SearchBar() {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 500);

  useEffect(() => {
    if (debouncedQuery) fetchResults(debouncedQuery);
  }, [debouncedQuery]);

  return (
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      placeholder="Search..."
    />
  );
}

Parameters

| Param | Type | Description | |---|---|---| | value | any | The value to debounce | | delay | number | Delay in milliseconds |

Returns: The debounced value.


useLocalStorage

Syncs React state with localStorage. Works just like useState but persists across page reloads.

import { useLocalStorage } from "hooknest";

function ThemeSwitcher() {
  const [theme, setTheme] = useLocalStorage("theme", "light");

  return (
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
      Current theme: {theme}
    </button>
  );
}

Parameters

| Param | Type | Description | |---|---|---| | key | string | The localStorage key | | initialValue | any | Default value if key doesn't exist |

Returns: [storedValue, setValue] — same API as useState.


useToggle

A minimal hook for boolean state with a stable toggle function.

import { useToggle } from "hooknest";

function Modal() {
  const [isOpen, toggle] = useToggle(false);

  return (
    <>
      <button onClick={toggle}>Open Modal</button>
      {isOpen && <dialog open>Hello! <button onClick={toggle}>Close</button></dialog>}
    </>
  );
}

Parameters

| Param | Type | Description | |---|---|---| | initialValue | boolean | Starting value (default: false) |

Returns: [value, toggle]


useOnClickOutside

Fires a callback whenever a click is detected outside the referenced element. Great for dropdowns, modals, and tooltips.

import { useOnClickOutside } from "hooknest";

function Dropdown() {
  const [open, setOpen] = useState(false);
  const ref = useRef();

  useOnClickOutside(ref, () => setOpen(false));

  return (
    <div ref={ref}>
      <button onClick={() => setOpen(!open)}>Toggle</button>
      {open && <ul><li>Option 1</li><li>Option 2</li></ul>}
    </div>
  );
}

Parameters

| Param | Type | Description | |---|---|---| | ref | RefObject | Ref attached to the target element | | handler | function | Callback to fire on outside click |


usePrevious

Returns the value from the previous render. Useful for comparing old and new state, or animating between values.

import { usePrevious } from "hooknest";

function Counter() {
  const [count, setCount] = useState(0);
  const previous = usePrevious(count);

  return (
    <>
      <p>Now: {count} | Before: {previous ?? "—"}</p>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
    </>
  );
}

Parameters

| Param | Type | Description | |---|---|---| | value | any | The value to track |

Returns: The value from the previous render (undefined on first render).


useCopyToClipboard

Copies a string to the clipboard and exposes a copied flag that auto-resets after a timeout.

import { useCopyToClipboard } from "hooknest";

function CopyButton({ text }) {
  const { copied, copy } = useCopyToClipboard();

  return (
    <button onClick={() => copy(text)}>
      {copied ? "Copied! ✅" : "Copy to clipboard"}
    </button>
  );
}

Returns

| Property | Type | Description | |---|---|---| | copy | function(text) | Call with the string to copy | | copied | boolean | true for ~2 seconds after a successful copy |


Requirements

  • React >= 17.0.0
  • Node.js >= 14
  • ESM-compatible bundler (Vite, Next.js, Webpack 5+)

Contributing

Contributions, issues and feature requests are welcome!

  1. Fork the repo
  2. Create your branch: git checkout -b feat/my-hook
  3. Commit your changes: git commit -m 'feat: add useMyHook'
  4. Push to the branch: git push origin feat/my-hook
  5. Open a Pull Request

Author

Nimit Gupta · @nimit726


License

MIT © Nimit Gupta