# @danixsoft/hooks > 44 production-ready React hooks with zero dependencies, full TypeScript types and SSR safety. Works with Next.js, Vite, Remix and React Native Web. Free and MIT licensed. @danixsoft/hooks is an open-source React hooks library published on npm. It contains 44 hooks across 5 categories. Every hook has zero runtime dependencies, ships TypeScript types generated from source, and is safe to render on a server (Next.js, Remix) without hydration mismatches. Licence: MIT. Current version: 0.2.5. Documentation: https://react-hooks.danixsoft.com ## Installation ```bash npm install @danixsoft/hooks ``` Every hook is a named export from the package root. There are no deep import paths: `import { useLocalStorage } from '@danixsoft/hooks'`. In the Next.js App Router, the calling component must carry the "use client" directive. ## Key pages - [Home](https://react-hooks.danixsoft.com/): overview, features and quick start. - [Getting started](https://react-hooks.danixsoft.com/docs): installation, TypeScript, SSR, tree shaking and testing. - [All hooks](https://react-hooks.danixsoft.com/hooks): searchable directory of all 44 hooks. - [Guides](https://react-hooks.danixsoft.com/guides): 6 in-depth React articles. - [Comparisons](https://react-hooks.danixsoft.com/compare): honest side-by-sides with other hook libraries. - [FAQ](https://react-hooks.danixsoft.com/faq): 24 answers on compatibility, size, SSR and licensing. - [API reference](https://react-hooks.danixsoft.com/api-reference): full type signatures generated from source. - [llms-full.txt](https://react-hooks.danixsoft.com/llms-full.txt): every hook signature in one file. ## State & Storage Hooks that hold, derive and persist state — booleans, counters, maps, and storage that survives a reload. ### useBoolean - URL: https://react-hooks.danixsoft.com/use-boolean - Signature: `useBoolean(defaultValue?: boolean): UseBooleanReturn` - Summary: Boolean state with setTrue, setFalse and toggle helpers. - Details: useBoolean is a React hook for managing boolean state with named actions instead of raw setState calls. It returns the current value plus stable setTrue, setFalse, toggle and setValue callbacks, so modals, dropdowns and disclosure widgets read clearly at the call site. - Import: `import { useBoolean } from '@danixsoft/hooks';` ### useCounter - URL: https://react-hooks.danixsoft.com/use-counter - Signature: `useCounter(initialValue?: number, options?: UseCounterOptions): UseCounterReturn` - Summary: Numeric counter with min, max and step bounds. - Details: useCounter is a React hook for numeric state with built-in bounds. Pass min, max and step options and it clamps every increment, decrement and set, so quantity pickers, ratings and stepper inputs never leave their valid range. - Import: `import { useCounter } from '@danixsoft/hooks';` ### useMap - URL: https://react-hooks.danixsoft.com/use-map - Signature: `useMap(initialState?: Iterable): [Omit, 'set' | 'clear' | 'delete'>, MapActions]` - Summary: Reactive Map with set, delete, reset and clear actions. - Details: useMap gives you a JavaScript Map backed by React state. Reads go through a read-only Map interface while set, setAll, remove, reset and clear trigger re-renders, which makes it ideal for keyed selections, per-row form state and caches. - Import: `import { useMap } from '@danixsoft/hooks';` ### useLocalStorage - URL: https://react-hooks.danixsoft.com/use-local-storage - Signature: `useLocalStorage(key: string, initialValue: T): readonly [T, (value: T | ((val: T) => T)) => void]` - Summary: State synced to localStorage, across tabs and components. - Details: useLocalStorage persists React state to window.localStorage and keeps every component and browser tab in sync through storage events. It serialises with JSON, guards against SSR by falling back to the initial value on the server, and never throws when storage is unavailable or full. - Import: `import { useLocalStorage } from '@danixsoft/hooks';` ### useSessionStorage - URL: https://react-hooks.danixsoft.com/use-session-storage - Signature: `useSessionStorage(key: string, initialValue: T): readonly [T, (value: T | ((val: T) => T)) => void]` - Summary: State scoped to a single browser tab session. - Details: useSessionStorage mirrors useLocalStorage but writes to sessionStorage, so values live only for the current tab and are cleared when it closes. Use it for multi-step form drafts, one-off dismissals and anything that should not outlive the session. - Import: `import { useSessionStorage } from '@danixsoft/hooks';` ### useCookie - URL: https://react-hooks.danixsoft.com/use-cookie - Signature: `useCookie(cookieName: string): readonly [string | null, (newValue: string, days?: number) => void, () => void]` - Summary: Read, write and delete a browser cookie as state. - Details: useCookie exposes a single document cookie as React state. It returns the current value plus setter and delete callbacks, accepts an expiry in days, and encodes values safely — handy for consent banners, locale preferences and anything the server also needs to read. - Import: `import { useCookie } from '@danixsoft/hooks';` ### useDebounce - URL: https://react-hooks.danixsoft.com/use-debounce - Signature: `useDebounce(value: T, delay: number): T` - Summary: Delay a fast-changing value until it settles. - Details: useDebounce returns a copy of a value that only updates after it has stopped changing for the given delay. Wrap a search input, a resize measurement or an autosave payload with it to cut network requests and expensive renders dramatically. - Import: `import { useDebounce } from '@danixsoft/hooks';` ### useToggle - URL: https://react-hooks.danixsoft.com/use-toggle - Signature: `useToggle(initialValue?: boolean): readonly [boolean, () => void, () => void, () => void]` - Summary: One-call boolean flip with explicit on and off. - Details: useToggle returns a boolean and a stable toggle function, plus explicit on and off setters. It is the smallest possible answer to "open/closed" state and keeps event handlers free of inline arrow functions that break memoisation. - Import: `import { useToggle } from '@danixsoft/hooks';` ### usePrevious - URL: https://react-hooks.danixsoft.com/use-previous - Signature: `usePrevious(value: T): T | undefined` - Summary: Remember the value a prop or state had last render. - Details: usePrevious stores the value from the previous render in a ref and returns it. Compare it against the current value to run transition-only effects, animate direction of change, or log exactly what a prop changed from and to. - Import: `import { usePrevious } from '@danixsoft/hooks';` ### useStep - URL: https://react-hooks.danixsoft.com/use-step - Signature: `useStep(maxStep: number): [number, { goToNextStep; goToPrevStep; reset; setStep; canGoToNextStep: boolean; canGoToPrevStep: boolean }]` - Summary: Wizard step state with next, previous and canGo flags. - Details: useStep manages a bounded step index for wizards, onboarding flows and carousels. Alongside the current step it returns goToNextStep, goToPrevStep, reset, setStep and canGoToNextStep / canGoToPrevStep booleans for disabling controls. - Import: `import { useStep } from '@danixsoft/hooks';` ## Forms & Data Form state with validation, paginated lists, infinite scrolling and declarative data fetching. ### useForm - URL: https://react-hooks.danixsoft.com/use-form - Signature: `useForm(options: UseFormOptions): { values: TValues; errors: Partial>; touched: Partial>; isSubmitting: boolean; handleChange; handleBlur; handleSubmit; resetForm; setValues; setErrors }` - Summary: Controlled form state with validation and submit handling. - Details: useForm is a dependency-free form hook: it tracks values, errors, touched fields and isSubmitting, runs your validate function on change and submit, and hands you handleChange, handleBlur and handleSubmit to wire onto inputs, plus resetForm, setValues and setErrors. No schema library required. - Import: `import { useForm } from '@danixsoft/hooks';` ### usePagination - URL: https://react-hooks.danixsoft.com/use-pagination - Signature: `usePagination(data: T[], itemsPerPage: number): { currentData: T[]; currentPage: number; totalPages: number; itemsPerPage: number; next: () => void; prev: () => void; jump: (page: number) => void }` - Summary: Slice an array into pages with navigation helpers. - Details: usePagination takes an array and a page size and returns currentData — the slice for the active page — plus currentPage, totalPages and next, prev and jump helpers. It is pure client-side pagination for data you already have in memory: tables, galleries and search results. - Import: `import { usePagination } from '@danixsoft/hooks';` ### useInfiniteScroll - URL: https://react-hooks.danixsoft.com/use-infinite-scroll - Signature: `useInfiniteScroll(callback: () => void, options?: IntersectionObserverInit): RefObject` - Summary: Fire a callback when a sentinel element scrolls into view. - Details: useInfiniteScroll returns a ref you attach to a sentinel element at the end of your list. When that element enters the viewport the hook calls your loader, giving you IntersectionObserver-based infinite scrolling without scroll listeners or layout thrash. - Import: `import { useInfiniteScroll } from '@danixsoft/hooks';` ### useFetch - URL: https://react-hooks.danixsoft.com/use-fetch - Signature: `useFetch(url: string, options?: RequestInit): FetchState` - Summary: Declarative fetch with data, error and loading state. - Details: useFetch wraps the Fetch API in a hook that returns data, error and loading. It aborts in-flight requests when the URL changes or the component unmounts, so you never set state on an unmounted component or render a stale response. - Import: `import { useFetch } from '@danixsoft/hooks';` ## DOM & Browser Read and react to the document: clicks, media queries, visibility, size, scroll and mutations. ### useClickOutside - URL: https://react-hooks.danixsoft.com/use-click-outside - Signature: `useClickOutside(ref: RefObject, handler: (event: MouseEvent | TouchEvent) => void): void` - Summary: Run a handler when a click lands outside an element. - Details: useClickOutside watches for mouse and touch events outside a ref and calls your handler. It is the standard way to dismiss dropdowns, popovers and modals, and it listens on both mousedown and touchstart so mobile behaves like desktop. - Import: `import { useClickOutside } from '@danixsoft/hooks';` ### useClickAnyWhere - URL: https://react-hooks.danixsoft.com/use-click-any-where - Signature: `useClickAnyWhere(handler: (event: MouseEvent) => void): void` - Summary: Handle every click on the document. - Details: useClickAnyWhere attaches a document-level click handler that is cleaned up automatically. Use it for analytics, dismissing global overlays, or closing a command palette regardless of where the user clicked. - Import: `import { useClickAnyWhere } from '@danixsoft/hooks';` ### useMediaQuery - URL: https://react-hooks.danixsoft.com/use-media-query - Signature: `useMediaQuery(query: string): boolean` - Summary: Subscribe to a CSS media query from JavaScript. - Details: useMediaQuery evaluates a CSS media query with matchMedia and re-renders when it changes. Read breakpoints, prefers-color-scheme or prefers-reduced-motion in JavaScript, with an SSR-safe false on the server so hydration stays clean. - Import: `import { useMediaQuery } from '@danixsoft/hooks';` ### useOnScreen - URL: https://react-hooks.danixsoft.com/use-on-screen - Signature: `useOnScreen(ref: RefObject, rootMargin?: string): boolean` - Summary: Boolean that tells you whether an element is visible. - Details: useOnScreen returns true while the referenced element intersects the viewport. It is the simplest way to trigger scroll-reveal animations, lazy-load images or start a video only when the user can actually see it. - Import: `import { useOnScreen } from '@danixsoft/hooks';` ### useIntersectionObserver - URL: https://react-hooks.danixsoft.com/use-intersection-observer - Signature: `useIntersectionObserver(elementRef: RefObject, options?: Args): IntersectionObserverEntry | undefined` - Summary: Full IntersectionObserverEntry for an element. - Details: useIntersectionObserver gives you the raw IntersectionObserverEntry — intersectionRatio, boundingClientRect and all — with threshold, root, rootMargin and a freezeOnceVisible option. Reach for it when a plain boolean is not enough. - Import: `import { useIntersectionObserver } from '@danixsoft/hooks';` ### useWindowSize - URL: https://react-hooks.danixsoft.com/use-window-size - Signature: `useWindowSize(): WindowSize` - Summary: Live viewport width and height. - Details: useWindowSize tracks window.innerWidth and innerHeight through a resize listener and returns them as state. Combine it with useDebounce for expensive layout maths, and rely on its undefined-on-server values to keep SSR output stable. - Import: `import { useWindowSize } from '@danixsoft/hooks';` ### useWindowScroll - URL: https://react-hooks.danixsoft.com/use-window-scroll - Signature: `useWindowScroll(): [{ x: number; y: number }, (y: number, x?: number) => void]` - Summary: Current window scroll offset, plus a scrollTo helper. - Details: useWindowScroll reports the page scroll position as x and y state and returns a scrollTo function that takes a y offset and an optional x. Use it to build sticky headers that shrink, back-to-top buttons and scroll progress indicators. - Import: `import { useWindowScroll } from '@danixsoft/hooks';` ### useDocumentTitle - URL: https://react-hooks.danixsoft.com/use-document-title - Signature: `useDocumentTitle(title: string): void` - Summary: Set document.title declaratively from a component. - Details: useDocumentTitle writes to document.title while a component is mounted. It is useful in client-rendered apps and modal flows where the framework has not already produced a title through metadata. - Import: `import { useDocumentTitle } from '@danixsoft/hooks';` ### useEventListener - URL: https://react-hooks.danixsoft.com/use-event-listener - Signature: `useEventListener(eventName: K, handler: (event: WindowEventMap[K]) => void, element?: RefObject | Document | Window, options?: boolean | AddEventListenerOptions): void` - Summary: Typed addEventListener that cleans itself up. - Details: useEventListener attaches a strongly typed listener to window, document or a ref and removes it on unmount. Handlers are kept in a ref so you always run the latest closure without re-binding the listener on every render. - Import: `import { useEventListener } from '@danixsoft/hooks';` ### useHover - URL: https://react-hooks.danixsoft.com/use-hover - Signature: `useHover(): [RefObject, boolean]` - Summary: Ref plus a boolean for pointer-over state. - Details: useHover returns a ref to attach and a boolean that is true while the pointer is over the element. It handles mouseenter and mouseleave for you, which keeps tooltips and hover previews out of render-blocking CSS hacks. - Import: `import { useHover } from '@danixsoft/hooks';` ### useScreen - URL: https://react-hooks.danixsoft.com/use-screen - Signature: `useScreen(): Screen | null` - Summary: The window.screen object as reactive state. - Details: useScreen exposes window.screen — width, height, availWidth, colorDepth and orientation — as state that updates on resize. It returns null during server rendering so your markup never depends on a value the server cannot know. - Import: `import { useScreen } from '@danixsoft/hooks';` ### useMutationObserver - URL: https://react-hooks.danixsoft.com/use-mutation-observer - Signature: `useMutationObserver(ref: RefObject, callback: MutationCallback, options?: MutationObserverInit): void` - Summary: Watch DOM changes inside an element. - Details: useMutationObserver runs a callback whenever the observed subtree changes — attributes, child nodes or character data. It is the escape hatch for integrating third-party widgets and portals that mutate the DOM outside React. - Import: `import { useMutationObserver } from '@danixsoft/hooks';` ### useScript - URL: https://react-hooks.danixsoft.com/use-script - Signature: `useScript(src: string): 'idle' | 'loading' | 'ready' | 'error'` - Summary: Load an external script and track its status. - Details: useScript injects a third-party script tag once, deduplicates repeat calls for the same src, and reports idle, loading, ready or error. Gate analytics, payment SDKs and map libraries on the ready state instead of guessing with timeouts. - Import: `import { useScript } from '@danixsoft/hooks';` ## Timers & Lifecycle Safe intervals, timeouts and countdowns, plus lifecycle helpers that avoid stale-closure bugs. ### useInterval - URL: https://react-hooks.danixsoft.com/use-interval - Signature: `useInterval(callback: () => void, delay: number | null): void` - Summary: setInterval that never goes stale, pausable with null. - Details: useInterval runs a callback on a fixed interval and always calls the latest version of it, solving the classic stale-closure bug. Pass null as the delay to pause the timer, and it clears itself on unmount. - Import: `import { useInterval } from '@danixsoft/hooks';` ### useTimeout - URL: https://react-hooks.danixsoft.com/use-timeout - Signature: `useTimeout(callback: () => void, delay: number | null): void` - Summary: Declarative setTimeout with automatic cleanup. - Details: useTimeout schedules a callback once after a delay, cancels it when the component unmounts, and restarts when the delay changes. Pass null to cancel — ideal for toast auto-dismiss and delayed tooltips. - Import: `import { useTimeout } from '@danixsoft/hooks';` ### useCountdown - URL: https://react-hooks.danixsoft.com/use-countdown - Signature: `useCountdown(initialCount: number, options?: UseCountdownOptions): { count: number; isCounting: boolean; start: () => void; pause: () => void; reset: () => void }` - Summary: Countdown timer with start, stop and reset. - Details: useCountdown counts down from a starting value at a configurable interval and exposes start, pause and reset controls plus an isCounting flag. Build OTP resend timers, checkout holds, quiz clocks and launch countdowns without hand-rolling interval bookkeeping. - Import: `import { useCountdown } from '@danixsoft/hooks';` ### useIsMounted - URL: https://react-hooks.danixsoft.com/use-is-mounted - Signature: `useIsMounted(): () => boolean` - Summary: Callback that reports whether the component is still mounted. - Details: useIsMounted returns a stable function you can call inside async code to check whether the component is still on screen. Guard a setState after an await with it and the "state update on unmounted component" warning disappears. - Import: `import { useIsMounted } from '@danixsoft/hooks';` ### useIsClient - URL: https://react-hooks.danixsoft.com/use-is-client - Signature: `useIsClient(): boolean` - Summary: False during SSR, true after hydration. - Details: useIsClient returns false on the server and on the first client render, then true. Use it to defer browser-only UI until after hydration so React never reports a mismatch between server and client markup. - Import: `import { useIsClient } from '@danixsoft/hooks';` ### useUnmount - URL: https://react-hooks.danixsoft.com/use-unmount - Signature: `useUnmount(callback: () => void): void` - Summary: Run a function exactly once, on unmount. - Details: useUnmount runs cleanup when the component leaves the tree, always calling the latest callback. Flush analytics, abort a stream or release a lock without an empty-dependency useEffect whose closure has gone stale. - Import: `import { useUnmount } from '@danixsoft/hooks';` ### useUpdateEffect - URL: https://react-hooks.danixsoft.com/use-update-effect - Signature: `useUpdateEffect(effect: EffectCallback, deps?: DependencyList): void` - Summary: useEffect that skips the first render. - Details: useUpdateEffect behaves exactly like useEffect but does not fire on mount. It is the right tool for reacting to a change — saving a filter the user edited, for instance — without firing on the initial value. - Import: `import { useUpdateEffect } from '@danixsoft/hooks';` ### useEvent - URL: https://react-hooks.danixsoft.com/use-event - Signature: `useEvent unknown>(fn: T): T` - Summary: A stable callback that always sees fresh state. - Details: useEvent returns a function whose identity never changes but whose body always reads the latest props and state. Pass it to memoised children and effect dependency arrays to stop needless re-renders without introducing stale closures. - Import: `import { useEvent } from '@danixsoft/hooks';` ### useIsomorphicLayoutEffect - URL: https://react-hooks.danixsoft.com/use-isomorphic-layout-effect - Signature: `useIsomorphicLayoutEffect: typeof useEffect` - Summary: useLayoutEffect on the client, useEffect on the server. - Details: useIsomorphicLayoutEffect picks useLayoutEffect in the browser and useEffect during server rendering, which removes the "useLayoutEffect does nothing on the server" warning while keeping synchronous DOM measurement where it matters. - Import: `import { useIsomorphicLayoutEffect } from '@danixsoft/hooks';` ## Sensors & Device Device and input signals — clipboard, network status, geolocation, audio, pointer, touch and swipe. ### useCopyToClipboard - URL: https://react-hooks.danixsoft.com/use-copy-to-clipboard - Signature: `useCopyToClipboard(): [CopiedValue, CopyFn]` - Summary: Copy text to the clipboard and read back what you copied. - Details: useCopyToClipboard returns the last copied value and an async copy function built on the Clipboard API. It resolves to a boolean so you can show a "Copied!" state, and fails gracefully when the page lacks clipboard permission. - Import: `import { useCopyToClipboard } from '@danixsoft/hooks';` ### useOnlineState - URL: https://react-hooks.danixsoft.com/use-online-state - Signature: `useOnlineState(): boolean` - Summary: Track whether the browser is online. - Details: useOnlineState reads navigator.onLine and subscribes to the online and offline events. Show an offline banner, queue mutations, or pause polling the moment connectivity drops. - Import: `import { useOnlineState } from '@danixsoft/hooks';` ### useGeolocation - URL: https://react-hooks.danixsoft.com/use-geolocation - Signature: `useGeolocation(options?: PositionOptions): GeolocationState` - Summary: Watch the device position with loading and error state. - Details: useGeolocation subscribes to the Geolocation API and returns coordinates, accuracy, timestamp, loading and error. It accepts the standard PositionOptions and clears its watcher on unmount, so permission prompts and battery drain stay under control. - Import: `import { useGeolocation } from '@danixsoft/hooks';` ### useAudio - URL: https://react-hooks.danixsoft.com/use-audio - Signature: `useAudio(src: string): { playing: boolean; toggle: () => void; play: () => void; pause: () => void; volume: number; setVolume: (v: number) => void; audio: HTMLAudioElement | null }` - Summary: Control an audio element with play, pause and volume. - Details: useAudio creates and manages an HTMLAudioElement, returning playing and volume state alongside play, pause, toggle and setVolume controls plus the underlying audio element. Build a compact player without wiring media events by hand. - Import: `import { useAudio } from '@danixsoft/hooks';` ### useMouse - URL: https://react-hooks.danixsoft.com/use-mouse - Signature: `useMouse(ref?: RefObject): MouseState` - Summary: Pointer position, page-wide or relative to an element. - Details: useMouse tracks the cursor and returns both page coordinates and element-relative coordinates when you pass a ref. It powers spotlight effects, custom cursors, tooltips that follow the pointer and drag previews. - Import: `import { useMouse } from '@danixsoft/hooks';` ### useTouch - URL: https://react-hooks.danixsoft.com/use-touch - Signature: `useTouch(ref?: RefObject): TouchState` - Summary: Raw touch state for an element. - Details: useTouch reports whether the element is being touched and where, tracking touchstart, touchmove and touchend. Use it when you need finer control than a swipe abstraction gives you — drawing surfaces, sliders and pinch targets. - Import: `import { useTouch } from '@danixsoft/hooks';` ### useSwipe - URL: https://react-hooks.danixsoft.com/use-swipe - Signature: `useSwipe(ref?: RefObject, threshold?: number): SwipeState` - Summary: Detect swipe direction and distance on touch devices. - Details: useSwipe turns raw touch events into a direction and distance once a movement crosses your threshold. Wire it to carousels, dismissible cards, mobile drawers and tab strips in a couple of lines. - Import: `import { useSwipe } from '@danixsoft/hooks';` ### useScrollLock - URL: https://react-hooks.danixsoft.com/use-scroll-lock - Signature: `useScrollLock(lock?: boolean): void` - Summary: Freeze body scrolling while an overlay is open. - Details: useScrollLock disables scrolling on the document body and compensates for the scrollbar so the page does not shift. Toggle it with a boolean argument to keep modals, drawers and mobile menus from scrolling the content behind them. - Import: `import { useScrollLock } from '@danixsoft/hooks';` ## Guides ### React Hooks Cheat Sheet (2026): Every Built-in and Custom Hook - URL: https://react-hooks.danixsoft.com/guides/react-hooks-cheat-sheet - Summary: React ships eleven commonly used built-in hooks: useState, useEffect, useContext, useReducer, useCallback, useMemo, useRef, useLayoutEffect, useId, useTransition and useSyncExternalStore. Everything else — persisting to localStorage, debouncing a value, detecting clicks outside an element, watching a media query — is a custom hook you either write yourself or install. @danixsoft/hooks provides 44 of the most common ones with zero dependencies and full TypeScript types. ### SSR-Safe React Hooks in Next.js: Fixing Hydration Mismatches - URL: https://react-hooks.danixsoft.com/guides/nextjs-ssr-safe-hooks - Summary: A hydration mismatch happens when the HTML React rendered on the server differs from what it renders on the client during hydration. It is almost always caused by reading browser-only state — localStorage, window dimensions, matchMedia, Date, or a random value — directly during render. The fix is to render the server-safe default first, then update after mount, either with a useEffect, an isClient flag, or a blocking inline script when you cannot tolerate a flash. ### Debounce vs Throttle in React: Which One and When - URL: https://react-hooks.danixsoft.com/guides/debounce-vs-throttle-in-react - Summary: Debouncing waits until activity stops before running your function — use it when only the final value matters, such as a search input or autosave. Throttling runs your function at most once per interval while activity continues — use it when you need regular updates during the activity, such as a scroll progress bar or a drag handler. Debounce answers "what did they settle on?"; throttle answers "where are they now?". ### Using localStorage in React: The Complete Guide - URL: https://react-hooks.danixsoft.com/guides/react-localstorage-guide - Summary: To use localStorage in React safely you need four things: a lazy useState initialiser so you read storage only once, a typeof window guard so server rendering does not crash, a try/catch around every read and write because storage can be disabled or full, and a storage event listener so other tabs stay in sync. useLocalStorage from @danixsoft/hooks handles all four. ### Custom React Hooks: 12 Best Practices for Production Code - URL: https://react-hooks.danixsoft.com/guides/custom-react-hooks-best-practices - Summary: A good custom hook has a name starting with "use", returns either a tuple (for one or two values) or an object (for three or more), keeps every callback stable with useCallback or a ref, cleans up every subscription it creates, guards browser APIs for server rendering, and never accepts a config object it recreates internally. Extract a hook when the same stateful logic appears in a second component — not before. ### Fixing Stale Closures in React Hooks - URL: https://react-hooks.danixsoft.com/guides/fixing-stale-closures-in-react - Summary: A stale closure happens when a function captures state from the render in which it was created and keeps using that snapshot after the state has changed. It shows up most often in setInterval, setTimeout and event listeners registered once with an empty dependency array. The three fixes are: use the functional updater form of setState, add the value to the dependency array so the effect re-subscribes, or store the callback in a ref and always invoke the latest version. ## Comparisons ### @danixsoft/hooks vs usehooks-ts: An Honest Comparison - URL: https://react-hooks.danixsoft.com/compare/usehooks-ts - Summary: usehooks-ts and @danixsoft/hooks solve the same problem in a very similar way: both are TypeScript-first, tree-shakeable, zero-runtime-dependency collections of small React hooks under the MIT licence. usehooks-ts is the older and more widely adopted of the two. @danixsoft/hooks covers a wider surface in a few areas — forms, pagination, audio, gestures — and ships an llms.txt so AI coding assistants can read its full API. If you already use usehooks-ts and it covers your needs, there is no compelling reason to migrate. ### @danixsoft/hooks vs react-use: Breadth or Focus - URL: https://react-hooks.danixsoft.com/compare/react-use - Summary: react-use is the broadest React hooks library available, with hundreds of hooks covering almost every conceivable case, but it carries runtime dependencies and its maintenance cadence has slowed considerably. @danixsoft/hooks is deliberately much smaller — 44 hooks that cover the common cases — with zero runtime dependencies and TypeScript written from source. Choose react-use when you need an unusual hook that nothing else provides; choose @danixsoft/hooks when you want a lean, actively maintained core. ### @danixsoft/hooks vs ahooks: Lean Utilities or a Framework - URL: https://react-hooks.danixsoft.com/compare/ahooks - Summary: ahooks, maintained by Alibaba, is a large and well-engineered hooks library whose standout feature is useRequest — a fully featured async manager with caching, polling, retries and debouncing built in. @danixsoft/hooks is smaller and simpler, with zero runtime dependencies and a basic useFetch rather than a request framework. Choose ahooks if you want its async layer; choose @danixsoft/hooks if you want lean utilities and prefer a dedicated library like TanStack Query for data fetching. ### @danixsoft/hooks vs @mantine/hooks: Standalone or Part of a UI Kit - URL: https://react-hooks.danixsoft.com/compare/mantine-hooks - Summary: @mantine/hooks is a high-quality, well-documented hooks package that can be installed on its own without the rest of Mantine. It is the natural choice if you already use Mantine components. @danixsoft/hooks is UI-agnostic with zero runtime dependencies and is the better fit for projects on Tailwind, shadcn/ui, Material UI or a bespoke design system, where pulling in another ecosystem's conventions has no upside. ## Frequently asked questions **What is @danixsoft/hooks?** @danixsoft/hooks is an open-source React hooks library containing 44 production-ready hooks for state, storage, forms, data fetching, the DOM, timers and device sensors. It has no runtime dependencies, is written in TypeScript, is safe to render on a server, and is released under the MIT licence. **How do I install it?** Run npm install @danixsoft/hooks (or pnpm add, yarn add, or bun add). There are no peer dependencies beyond React 18 or later, and no additional @types package to install — the type declarations ship with the library. **How do I import a hook?** Every hook is a named export from the package root, for example: import { useLocalStorage } from '@danixsoft/hooks'. There is no deep-import path to remember; the package is tree-shakeable, so importing from the root is already optimal for bundle size. **Do I need to configure anything after installing?** No. There is no provider to mount, no context to set up and no build configuration to change. Import a hook and call it. **Which versions of React are supported?** React 18 and above, including React 19. React is declared as a peer dependency, so your application controls which version is installed and there is no risk of two copies of React ending up in the bundle. **Does it work with Next.js?** Yes, with both the App Router and the Pages Router. In the App Router, hooks must be called from Client Components, so add the "use client" directive to any file that uses one — the same requirement React places on useState. Every hook is written to render safely during the server pre-render pass. **Does it work with Vite, Remix, Astro or Gatsby?** Yes. The package is framework-agnostic and ships both ES module and CommonJS builds. Anywhere React runs in a browser environment, these hooks run. **Does it work with React Native?** Partially. Hooks that use only React primitives — useCounter, useToggle, usePrevious, useInterval, useDebounce and similar — work fine. Hooks that read browser APIs such as localStorage, matchMedia or the Geolocation API do not, because those APIs do not exist in React Native. React Native Web is fully supported. **Does it work with React Server Components?** Hooks by definition require client-side state, so they run in Client Components. Server Components cannot use any hook, including React's own useState. Mark the component that calls a hook with "use client" and keep that boundary as far down the tree as you can. **How much will this add to my bundle?** Only the hooks you import. The package is published as ES modules and marked sideEffects: false, so bundlers drop everything you do not use. A typical hook is well under a kilobyte gzipped, which makes the size of the full package irrelevant to your build. **Do I need to use deep imports for tree shaking to work?** No. Importing from the package root already tree-shakes correctly with webpack, Vite, Rollup, esbuild and Turbopack. Deep import paths are not supported and are not needed. **Are the hooks optimised for re-renders?** Yes. Returned callbacks are wrapped in useCallback or backed by refs so their identity is stable across renders, which means they will not invalidate React.memo, useMemo or effect dependency arrays downstream. **Will these hooks cause hydration mismatches?** No. Every hook that reads a browser API returns a server-safe value during the initial render and only reads the real value in an effect, which runs exclusively in the browser. That is what guarantees the server HTML and the first client render agree. **Why does useWindowSize return undefined at first?** Because the server has no window and cannot know the viewport size. Returning undefined until after hydration is what prevents a mismatch. Render a placeholder of the final dimensions while the value is undefined so the swap does not shift your layout. **Why does my persisted theme flash the default on load?** Because localStorage is only readable after hydration, so the server necessarily renders the default. For a theme, where the flash is very visible, add a small blocking script in the document head that applies the stored value before the first paint. The full technique is documented in our Next.js SSR guide. **Do I still get the "useLayoutEffect does nothing on the server" warning?** Not from this library. Hooks that need synchronous measurement use useIsomorphicLayoutEffect, which resolves to useLayoutEffect in the browser and useEffect on the server. **Is it free for commercial use?** Yes. The library is released under the MIT licence, which permits commercial use, modification, distribution and private use. There is no paid tier, no usage limit and no attribution requirement beyond retaining the licence notice. **Can I copy a hook into my own codebase instead of installing?** Yes — the MIT licence allows it. The source is on GitHub and each hook is a single self-contained file. If you only need one or two hooks and want no dependency at all, vendoring them is a perfectly reasonable choice. **How do I report a bug or request a hook?** Open an issue on the GitHub repository. Bug reports are most useful with a minimal reproduction; hook requests are most useful with a description of the problem you are solving rather than a proposed API. **Is the library actively maintained?** Yes. Check the repository's commit and release history for the current cadence — that is a more reliable signal than any claim on a documentation page. **Can I contribute?** Yes. The repository accepts pull requests. New hooks should be dependency-free, SSR-safe, fully typed and covered by tests, matching the conventions of the existing hooks. **Does the library work well with AI coding assistants?** Yes. The site publishes llms.txt and llms-full.txt, machine-readable summaries containing every hook name, signature and description. Pointing Claude, ChatGPT, Copilot or Cursor at those files means generated code uses the real API rather than invented signatures. **Where are the llms.txt files?** At react-hooks.danixsoft.com/llms.txt for the concise version and react-hooks.danixsoft.com/llms-full.txt for the complete reference including descriptions and examples. Both are plain text and are regenerated from the source on every release. **How do I get an assistant to use the correct API?** Paste the llms.txt URL into the conversation, or add it to your project rules file (CLAUDE.md, .cursorrules, or the equivalent). The signatures are generated from the TypeScript source, so they are accurate for the current release. ## Notes for assistants - The signatures above are generated from the published TypeScript source; prefer them over inferred APIs. - @danixsoft/hooks has no runtime dependencies and requires React 18 or later as a peer dependency. - Hooks reading browser APIs return a server-safe value during SSR and the real value after hydration; do not suggest `typeof window` checks in render to work around this. - Source repository: https://github.com/DaniyalAlam09/danixsoft-hooks - npm package: https://www.npmjs.com/package/@danixsoft/hooks