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

craftysoft-hooks

v1.0.5

Published

A lightweight collection of essential React hooks for modern web apps.

Readme

Craftysoft Hooks

A professional, developer-friendly, and production-ready React custom hooks library with 20+ high-utility hooks that improve developer productivity.

npm version License: MIT

Features

  • 🎯 20+ Production-Ready Hooks - Carefully crafted hooks for common use cases
  • 📦 Tree-Shakeable - ESM support with zero dependencies (except React)
  • 🔒 Type-Safe - Full TypeScript support with JSDoc documentation
  • Performance Optimized - Memoized callbacks and optimized re-renders
  • 🌐 SSR-Safe - Works seamlessly with Next.js and other SSR frameworks
  • 🧪 Well Tested - Comprehensive test coverage with Vitest

Installation

npm install craftysoft-hooks
# or
yarn add craftysoft-hooks
# or
pnpm add craftysoft-hooks

🚀 Quick Start

import { useLocalStorage, useDebounce, useToggle } from "craftysoft-hooks";

function App() {
  const [theme, setTheme] = useLocalStorage("theme", "light");
  const [isOpen, toggle] = useToggle(false);
  const debouncedSearch = useDebounce(theme, 300);

  return (
    <div>
      <button onClick={toggle}>Toggle</button>
      <button onClick={() => setTheme("dark")}>Dark Mode</button>
    </div>
  );
}

Hooks Documentation

State Management Hooks

useLocalStorage

Store and sync data with localStorage.

const [value, setValue] = useLocalStorage("key", initialValue);

Example:

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

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

useSessionStorage

Manage sessionStorage data (similar to useLocalStorage but uses sessionStorage).

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

Example:

const [session, setSession] = useSessionStorage("sessionId", "");

return (
  <div>
    <p>Session: {session}</p>
    <button onClick={() => setSession("abc123")}>Set Session</button>
  </div>
);

useToggle

Manage boolean state easily with toggle functionality.

const [value, toggle, setTrue, setFalse] = useToggle(initialValue);

Example:

const [isOpen, toggle, setTrue, setFalse] = useToggle(false);

return (
  <div>
    <button onClick={toggle}>Toggle</button>
    <button onClick={setTrue}>Open</button>
    <button onClick={setFalse}>Close</button>
    {isOpen && <div>Content</div>}
  </div>
);

usePrevious

Track the previous value of a state or prop.

const previousValue = usePrevious(value);

Example:

const [count, setCount] = useState(0);
const prevCount = usePrevious(count);

return (
  <div>
    <p>Current: {count}</p>
    <p>Previous: {prevCount}</p>
    <button onClick={() => setCount(count + 1)}>Increment</button>
  </div>
);

useCounter

Simple counter with increment, decrement, reset, and set functions.

const { count, increment, decrement, reset, setValue } = useCounter(
  initialValue,
  step,
  min,
  max
);

Example:

const { count, increment, decrement, reset, setValue } = useCounter(0, 1, 0, 10);

return (
  <div>
    <p>Count: {count}</p>
    <button onClick={increment}>+</button>
    <button onClick={decrement}>-</button>
    <button onClick={reset}>Reset</button>
    <button onClick={() => setValue(5)}>Set to 5</button>
  </div>
);

Browser Hooks

useNetworkStatus

Detect online/offline network state.

const { isOnline, wasOffline } = useNetworkStatus();

Example:

const { isOnline, wasOffline } = useNetworkStatus();

return (
  <div>
    {!isOnline && <p>You are offline</p>}
    {wasOffline && <p>You were offline but are now back online</p>}
  </div>
);

useWindowSize

Track window width and height.

const { width, height } = useWindowSize();

Example:

const { width, height } = useWindowSize();

return (
  <div>
    Window size: {width} x {height}
  </div>
);

useMediaQuery

Listen to CSS media query changes.

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

Example:

const isMobile = useMediaQuery("(max-width: 768px)");

return <div>{isMobile ? "Mobile View" : "Desktop View"}</div>;

useScrollPosition

Get scroll position and direction.

const { x, y, direction } = useScrollPosition();

Example:

const { x, y, direction } = useScrollPosition();

return (
  <div>
    <p>Scroll X: {x}, Y: {y}</p>
    <p>Direction: {direction}</p>
  </div>
);

useElementSize

Observe element dimensions via ResizeObserver.

const ref = useRef<HTMLDivElement>(null);
const { width, height } = useElementSize(ref);

Example:

const ref = useRef<HTMLDivElement>(null);
const { width, height } = useElementSize(ref);

return (
  <div ref={ref}>
    <p>Width: {width}px, Height: {height}px</p>
  </div>
);

Utility Hooks

useClipboard

Copy text to clipboard with async support.

const { copiedText, copy } = useClipboard();

Example:

const { copiedText, copy } = useClipboard();

return (
  <button onClick={() => copy("Hello, World!")}>
    {copiedText ? `Copied: ${copiedText}` : "Copy"}
  </button>
);

Note: useCopyToClipboard is also exported for backward compatibility but is deprecated.


useDarkMode

Toggle and persist dark/light mode with system preference detection.

const { theme, themePreference, toggle, setDark, setLight, setSystem } = useDarkMode(initialValue);

Example:

const { theme, toggle, setDark, setLight } = useDarkMode("system");

useEffect(() => {
  document.documentElement.classList.toggle("dark", theme === "dark");
}, [theme]);

return (
  <button onClick={toggle}>
    Current theme: {theme}
  </button>
);

usePageVisibility

Detect if page is visible or hidden.

const isVisible = usePageVisibility();

Example:

const isVisible = usePageVisibility();

useEffect(() => {
  if (!isVisible) {
    // Pause video, animations, etc.
  }
}, [isVisible]);

useIdleTimer

Detect user inactivity.

const { isIdle, reset } = useIdleTimer(timeout, events);

Example:

const { isIdle, reset } = useIdleTimer(5000);

return (
  <div>
    {isIdle && <p>You've been idle for 5 seconds</p>}
    <button onClick={reset}>Reset Timer</button>
  </div>
);

Performance Hooks

useDebounce

Delay value updates until after a specified delay period.

const debouncedValue = useDebounce(value, delay);

Example:

const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search, 300);

useEffect(() => {
  if (debouncedSearch) {
    // Perform search API call
  }
}, [debouncedSearch]);

useThrottle

Limit how often a function can be called.

const throttledCallback = useThrottle(callback, delay);

Example:

const handleScroll = useThrottle(() => {
  console.log("Scroll event");
}, 200);

useEffect(() => {
  window.addEventListener("scroll", handleScroll);
  return () => window.removeEventListener("scroll", handleScroll);
}, [handleScroll]);

API Hooks

useFetch

Fetch data with loading, error, and data states.

const { data, loading, error, refetch } = useFetch<T>(url, options);

Example:

const { data, loading, error, refetch } = useFetch<User>("https://api.example.com/user");

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;

return <div>{data?.name}</div>;

Interaction Hooks

useClickOutside

Detect clicks outside of a specified element.

const ref = useRef<HTMLDivElement>(null);
useClickOutside(ref, callback);

Example:

const ref = useRef<HTMLDivElement>(null);

useClickOutside(ref, () => {
  setIsOpen(false);
});

return <div ref={ref}>Content</div>;

useKeyPress

Detect key presses.

const isPressed = useKeyPress("Enter");
// or for multiple keys
const isPressed = useKeyPress(["Control", "c"]);

Example:

const isEnterPressed = useKeyPress("Enter");
const isCtrlCPressed = useKeyPress(["Control", "c"]);

useEffect(() => {
  if (isEnterPressed) {
    console.log("Enter key is pressed");
  }
}, [isEnterPressed]);

useEventListener

Add and clean up event listeners safely.

useEventListener(eventName, handler, element, options);

Example:

useEventListener("scroll", () => {
  console.log("Window scrolled");
});

const ref = useRef<HTMLDivElement>(null);
useEventListener("click", handleClick, ref);

Testing

Run tests with Vitest:

npm test
npm run test:watch
npm run test:coverage

📖 TypeScript Support

All hooks are fully typed with TypeScript. Types are automatically included when you install the package.

import { useLocalStorage } from "@craftysoft/hooks";

// Fully typed with TypeScript
const [value, setValue] = useLocalStorage<string>("key", "initial");

SSR Support

All hooks are SSR-safe and work seamlessly with Next.js and other server-side rendering frameworks. Hooks that access browser APIs (like window, localStorage) automatically handle server-side rendering.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © Md Shah Aman Patwary

Links


Made with ❤️ by the Md Shah Aman Patwary