Safeguard
Open Source

usehooks-ts: A Typed React Hooks Library Reviewed

usehooks-ts packs 30+ typed React hooks into a tree-shakable package with a single dependency. Here is what it does well, where it is aging, and how to vet it before adoption.

Karan Patel
Platform Engineer
7 min read

usehooks-ts is a TypeScript-first collection of ready-made React hooks that covers the utility layer most teams keep rewriting by hand, and it does so with exactly one runtime dependency. If you have ever copied a useLocalStorage or useOnClickOutside implementation from a blog post into your fifth project, this package exists to end that ritual. At version 3.1.1 it ships 30+ hooks, is fully tree-shakable via its ESM build, and sits at roughly four million weekly downloads on npm. This review looks at what you actually get, what changed in v3, and the questions worth asking before you add it to a production dependency tree.

What the library actually contains

The npm usehooks-ts package is not a framework. It is a flat catalog of small, focused hooks, each of which does one thing:

  • Storage and state: useLocalStorage, useSessionStorage, useReadLocalStorage, useMap, useBoolean, useCounter, useToggle, useStep
  • DOM and events: useEventListener, useOnClickOutside, useClickAnyWhere, useHover, useScrollLock, useWindowSize, useScreen, useResizeObserver, useIntersectionObserver
  • Timing: useInterval, useTimeout, useCountdown, useDebounceValue, useDebounceCallback
  • Environment: useMediaQuery, useDarkMode, useTernaryDarkMode, useIsClient, useIsomorphicLayoutEffect, useDocumentTitle, useScript, useCopyToClipboard

Every hook is written in TypeScript with real generics rather than any escapes. useLocalStorage<T> gives you a typed tuple back, useEventListener narrows the event type from the event name you pass, and useMap behaves like a stateful Map<K, V> without you writing the immutability plumbing.

Installation is the boring one-liner you would expect:

npm i usehooks-ts

and usage looks like this:

import { useLocalStorage, useDebounceValue } from 'usehooks-ts'

function SearchBox() {
  const [query, setQuery] = useLocalStorage('search-query', '')
  const [debouncedQuery] = useDebounceValue(query, 300)
  // fire the request with debouncedQuery
}

Because the ESM build is tree-shakable, importing two hooks does not drag the other thirty into your bundle.

The v3 rewrite: what changed and why it matters

Version 3 (the current major line, with 3.1.1 released in February 2025) was a breaking release that cleaned up several long-standing complaints:

  • The old useDebounce hook was split into useDebounceValue and useDebounceCallback, both built on lodash.debounce. That gives you cancel and flush controls the old implementation lacked.
  • Several SSR-hostile hooks gained explicit server-safety. useIsClient and useIsomorphicLayoutEffect exist precisely so Next.js users stop hitting hydration mismatches with useWindowSize-style hooks.
  • A handful of niche hooks were dropped rather than half-maintained, which is the right call for a utility library.

If you are migrating from v2, budget an hour: the renames are mechanical, but debounce call sites need attention because the return shape changed.

Dependency footprint and supply chain posture

This is where usehooks-ts genuinely earns points. Its entire runtime dependency tree is one package: lodash.debounce. Snyk's database lists no known direct vulnerabilities for the current release, and a one-dependency tree means your transitive exposure is close to nil.

Compare that with grabbing an equivalent grab-bag of hooks from three or four smaller packages, each with its own maintainer, release cadence, and transitive baggage. Fewer maintainers with publish rights over your dependency graph is a real, measurable reduction in supply chain risk, the same logic that makes people audit their SCA results for single-maintainer packages in the first place.

Two caveats worth stating honestly:

  1. lodash.debounce is one of the per-method lodash packages, and the lodash project's per-method packages have not seen releases in years. That is not a vulnerability, but it is a frozen dependency you inherit.
  2. The library is MIT licensed with no CLA weirdness, so license compliance is a non-issue.

Maintenance status: read this part before adopting

Here is the honest picture as of early 2025: the last release, 3.1.1, landed on February 5, 2025, and release cadence has slowed noticeably compared to the 2022–2023 era. Some dependency health tools already classify the project as "inactive" because of the long gaps between npm publishes.

Does that matter? For this specific package, less than it would for most. A hooks utility library has a small, stable API surface, no network-facing code, and React's hooks contract itself has not changed in years. "Finished" and "abandoned" look identical in a commit graph, and usehooks-ts is closer to finished.

That said, apply the standard checklist you would use for any dependency:

  • Is there a bus factor problem? Yes, it is primarily one maintainer's project, though it has 7.8k GitHub stars and a real contributor base.
  • Would you be stuck if it stopped? No. Every hook is small enough to vendor into your own codebase in minutes, and the MIT license permits exactly that.
  • Is the API likely to break underneath you? React 19 is the main forward risk; watch the repo's issue tracker when you plan your React upgrades.

That last exercise, checking whether a package still gets attention before you upgrade a framework around it, is exactly the kind of check an SCA tool such as Safeguard automates by flagging stale or unmaintained packages in your tree rather than waiting for a CVE to force the conversation.

Where it fits, and where it does not

usehooks-ts is a good fit when:

  • You want typed, tested implementations of the usual utility hooks without writing them.
  • You are on Next.js or another SSR framework and want hooks that already handle the server/client split.
  • You care about bundle size and want tree-shaking to actually work.

It is a poor fit when:

  • You need data-fetching hooks. That is TanStack Query's job, not this library's.
  • You need state management. useMap and useBoolean are conveniences, not a Zustand replacement.
  • Your team policy forbids dependencies that can be trivially vendored. In that case, vendor the two hooks you need and move on; the source is readable enough that this is a legitimate strategy.

Alternatives worth knowing

The comparison set is short:

  • react-use: the older, larger kitchen sink. More hooks, weaker TypeScript ergonomics, heavier dependency tree, and its own maintenance questions.
  • @uidotdev/usehooks: the hooks companion to the useHooks site, modern and well-documented, but a smaller catalog.
  • ahooks: Alibaba's library, very complete, but a much bigger install and a different design philosophy (more opinionated, more stateful machinery).
  • Write your own: for two or three hooks, honestly fine. For fifteen, you are just maintaining an unversioned fork of this library with fewer tests.

If your team is building out a shared frontend platform, it is worth running the same evaluation on all four; our security academy has a walkthrough on scoring open source dependencies on maintenance, footprint, and license before adoption.

Adoption checklist

Before you merge the PR that adds usehooks-ts:

  1. Pin the version (3.1.1 at the time of writing) and let your lockfile do its job.
  2. Confirm your bundler resolves the ESM build so tree-shaking works; check your bundle analyzer output for the package after the first build.
  3. Add it to your SCA scanning scope like any other dependency, one dependency is not zero dependencies.
  4. Note in your ADR (or wherever you record these decisions) that the vendoring escape hatch exists, so a future maintenance scare does not trigger a panicked migration.

That is a shorter checklist than most packages earn, which is the point: small API, tiny tree, permissive license, boring in the best sense.

FAQ

Is usehooks-ts still maintained?

Releases have slowed, with 3.1.1 (February 2025) being the latest, and some tooling flags the project as inactive. In practice the library is feature-complete and stable, and its small MIT-licensed hooks are trivial to vendor if development ever stops entirely.

Does usehooks-ts have any known vulnerabilities?

No. Snyk's vulnerability database lists no known direct vulnerabilities for current versions, and its only runtime dependency is lodash.debounce, which keeps transitive exposure minimal.

Does usehooks-ts work with Next.js and SSR?

Yes. Hooks like useIsClient, useIsomorphicLayoutEffect, and the storage hooks are written with server rendering in mind, which is one of its main advantages over older hook collections.

How is usehooks-ts different from react-use?

usehooks-ts is smaller, TypeScript-native, and tree-shakable with one dependency; react-use is a larger, older catalog with weaker typing and a heavier footprint. For most new TypeScript projects, usehooks-ts is the cleaner default.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.