
This repository holds two things:
The site imports the package straight from packages/react-hooks/src through a TypeScript path
alias, so every demo runs against the code in this repository, not the version on npm.
npm install @zenuilabs/react-hooks
See the package README for the quick start.
Requires Node 22.18 or newer.
npm install
npm --prefix packages/react-hooks install
npm run dev
| Command |
What it does |
npm run dev |
Starts the docs site on port 3000. |
npm run build |
Builds the static site into out/. |
npm run type-check |
Type-checks the site, demos and docs data. |
npm run pkg:build |
Builds the package with tsup. |
npm run pkg:test |
Builds the package and server-renders every hook in Node. |
npm run gen:readme |
Regenerates the hook tables in both READMEs from src/data. |
- Write the hook in
packages/react-hooks/src/hooks/useThing.ts. Export its option and result
types from the same file. It must not touch browser globals during render.
- Export it from
packages/react-hooks/src/index.ts (or the matching file in src/groups).
- Add a server-render case to the matching file in
packages/react-hooks/test/cases.
- Document it in the matching file in
src/data: description, category, level, signature,
usage example, parameters and return values.
- Build the live demo in
src/components/hook-examples/use-thing.tsx with the kit in
src/components/demo. The file name must be the hook name in kebab case. The demo registry
is generated from these file names on dev and build.
- Run
npm run pkg:test, npm run type-check and npm run gen:readme, then open a pull request.
The site reads the version from packages/react-hooks/package.json. The header, hero and footer
show it, and every hook whose since matches its major.minor is labelled new on the site and in
both READMEs. Bumping that one field updates all of them.
- Set
version in packages/react-hooks/package.json and since on each new hook in src/data.
- Run
npm run gen:readme and commit.
- Publish from
packages/react-hooks with npm publish --access public. prepublishOnly runs
the type-check and the server-render tests first.
- Tag the release (
git tag vX.Y.Z && git push origin vX.Y.Z) and create a GitHub release from
the tag. The site's changelog links point there.
- Run
npm run build and deploy out/.
91 hooks in 10 groups.
| Hook |
What it does |
useBroadcastState new |
State that stays in sync across every open tab of your site. |
useCounter |
Hold a number with stable increment, decrement, set and reset helpers. |
useLocalStorage |
Keep a piece of state in localStorage as JSON, synced across components and browser tabs. |
useMap new |
A Map in React state with immutable updates and stable action functions. |
usePrevious |
Return the value a variable had on the previous render. |
useQueue new |
A first-in, first-out queue in state. |
useSessionStorage |
Keep a piece of state in sessionStorage as JSON. |
useSet new |
A Set in React state with add, remove and toggle. |
useStateHistory new |
State with undo, redo and a browsable history. |
useStateMachine new |
A finite state machine from a typed config, with guards and entry and exit effects. |
useToggle |
Hold a boolean with stable helpers to flip it, set it and reset it. |
useUpdate |
Return a stable function that re-renders the component. |
| Hook |
What it does |
useAsync |
Run an async function and track its loading, error and data. |
useAsyncRetry |
Run an async function and retry it when it fails, with a fixed delay or backoff. |
useCachedFetch new |
Stale-while-revalidate data fetching with a cache shared by every component. |
useFetch |
Fetch JSON from a URL and track data, loading and error. |
useInfiniteScroll new |
Load the next page when a sentinel element at the end of a list scrolls into view. |
useOptimisticState new |
Show the result of an update immediately, run the real request, and roll back if it fails. |
useTaskQueue new |
Run async tasks in order with a limit on how many run at once. |
| Hook |
What it does |
useEventSource new |
Subscribe to a Server-Sent Events stream and keep the latest event in state. |
usePolling new |
Call an async function on an interval without overlapping calls. |
useWebSocket new |
Connect to a WebSocket and track its status, the latest message and reconnect attempts. |
| Hook |
What it does |
useDebounce |
Return a copy of a value that only updates after it has stopped changing for a set time. |
useDebouncedCallback new |
Wrap a function so it only runs after calls stop for a given delay. |
useThrottle |
Return a copy of a fast-changing value that updates at most once per interval. |
useThrottledCallback new |
Wrap a function so it runs at most once per interval while calls keep coming. |
useVirtualList new |
Render only the rows of a long list that are in view, with fixed or variable row heights. |
useWorker new |
Run a pure function in a Web Worker so heavy computation does not freeze the page. |
| Hook |
What it does |
useClickOutside |
Call a function when the user presses anywhere outside an element. |
useEvent |
Attach an event listener to the window, the document, an element or a ref, and remove it on unmount. |
useHover |
Track whether the pointer is over an element. |
useIntersection |
Report whether an element is on screen using IntersectionObserver. |
useKeyPress |
Return true while a specific key is held down. |
useLockBodyScroll |
Stop the page behind a modal, drawer or menu from scrolling. |
useMouse |
Track the pointer position in the viewport or relative to an element. |
useMouseWheel |
Read the deltas of the latest wheel or trackpad scroll event, on the window or on one element. |
useMutationObserver new |
Watch a DOM node for added or removed children, attribute changes and text edits. |
usePageLeave |
Call a function when the pointer leaves the page, for example toward the tab bar. |
useResizeObserver new |
Track the size of an element with ResizeObserver, batched to one update per animation frame. |
useScroll |
Track the scroll position and the direction of the last scroll, for the window or a scrollable element. |
useScrollSpy new |
Return the id of the section currently in view, based on IntersectionObserver. |
useTextSelection new |
Track the text the user has selected and where it is on screen, optionally limited to one container. |
useWindowSize |
Track the inner width and height of the browser window. |
| Hook |
What it does |
useDraggable new |
Drag an element with mouse, touch or pen, with axis locking, bounds and grid snapping. |
useDrop |
Turn an element into a drop target for files, text or links. |
useDropArea |
Turn an element into a drop zone for files, with optional type filtering. |
useFocusTrap new |
Keep keyboard focus inside a container while it is active, and give focus back when it closes. |
useHotkeys new |
Bind keyboard shortcuts, including combos like mod+k, several bindings at once and sequences like g h. |
useLongPress |
Call a function when an element is pressed and held for a set time, with mouse or touch. |
useRovingFocus new |
Give a group of controls a single Tab stop and move between them with the arrow keys, Home and End. |
useSwipe new |
Detect swipe gestures from mouse, touch or pen, with live offsets while the pointer moves. |
useTextareaAutosize new |
Grow a textarea to fit its content between a minimum and maximum number of rows. |
| Hook |
What it does |
useBattery new |
Reads the battery level and charging state from the Battery Status API. |
useBreakpoint new |
Reports the active min-width breakpoint using matchMedia, so by default components re-render only when a breakpoint is crossed. |
useColorScheme new |
Stores a light, dark or system color scheme preference and resolves it against the OS setting. |
useEyeDropper new |
Picks a color from anywhere on the screen with the EyeDropper API. |
useFileDialog new |
Opens the native file picker without rendering a file input. |
useGeolocation |
Watch the device position with the Geolocation API. |
useHash |
Read and update the URL hash. |
useIdle |
Report when the user has not moved the mouse, typed, scrolled or touched the page for a while. |
useLocation |
Track the pathname, query string and hash of the current URL. |
useMedia |
Track whether a CSS media query matches, such as a breakpoint, dark mode or reduced motion. |
useMediaDevices |
List the cameras, microphones and speakers the browser can see, and refresh when one is plugged in or removed. |
useNetworkState |
Track whether the browser is online, when that last changed, and the connection quality where the browser reports it. |
usePermission new |
Tracks the live state of a browser permission such as camera, microphone or geolocation. |
useReducedMotion new |
Returns true when the user has asked the OS to reduce motion. |
useSearchParam |
Read and write one query string parameter. |
useShare new |
Opens the native share sheet with the Web Share API. |
useVisibilityChange |
Track whether the page is visible or hidden in a background tab. |
useWakeLock new |
Keeps the screen from dimming with the Screen Wake Lock API. |
| Hook |
What it does |
useAudio |
Play a sound and track its playback state without rendering an audio element. |
useFullscreen |
Show one element in fullscreen mode and track whether it is there. |
useSpeechSynthesis new |
Reads text aloud with the Web Speech API. |
useVideo |
Control a video and track its playback state. |
| Hook |
What it does |
useAnimationFrame new |
Run a callback on every animation frame with the time since the previous frame. |
useCountdown new |
Count down to a date or through a duration and expose days, hours, minutes and seconds. |
useInterval |
Run a callback on a fixed interval that pauses when the delay is null. |
useSpringValue new |
Animate a number toward a target with spring physics. |
useStopwatch new |
A stopwatch with start, pause, reset and laps. |
useTimeAgo new |
Format a date as relative time, such as "3 minutes ago" or "in 2 days", and keep it up to date. |
| Hook |
What it does |
useCookie |
Read and write one browser cookie as React state. |
useCopyToClipboard |
Copy text to the clipboard and get a short-lived flag for "Copied" feedback. |
useDeepCompareEffect new |
Works like useEffect but compares dependencies by value. |
useDocumentTitle new |
Sets document.title while the component is mounted and restores the previous title when it unmounts. |
useEventCallback new |
Returns a function with a stable identity that always calls the latest version of your callback. |
useIsClient new |
Returns false during server rendering and the first client render, then true. |
useIsMounted new |
Returns a function that reports whether the component is still mounted. |
useIsomorphicLayoutEffect new |
useLayoutEffect in the browser and useEffect on the server. |
useLatest new |
Returns a ref that always holds the latest value. |
useScript new |
Loads an external script and reports its status. |
useWhyDidYouUpdate new |
A development helper that reports which props changed since the last render. |
MIT © ZenUI Labs