react-use vs @uidotdev/usehooks vs ahooks
React Custom Hook Libraries for Modern Web Development
react-use@uidotdev/usehooksahooksSimilar Packages:

React Custom Hook Libraries for Modern Web Development

@uidotdev/usehooks, ahooks, and react-use are all libraries that provide reusable React custom hooks to simplify common frontend tasks like state management, side effects, browser APIs, and performance optimizations. These packages help developers avoid reinventing the wheel by offering well-tested, composable hooks that follow React best practices. While they share overlapping functionality, they differ significantly in API design philosophy, TypeScript support, feature scope, and target use cases.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-use3,016,07343,947454 kB653a year agoUnlicense
@uidotdev/usehooks736,03611,40443 kB832 years agoMIT
ahooks014,923621 kB2664 months agoMIT

React Custom Hook Libraries Compared: @uidotdev/usehooks vs ahooks vs react-use

When building React applications, custom hooks are essential for encapsulating logic, managing side effects, and interacting with browser APIs. The three libraries — @uidotdev/usehooks, ahooks, and react-use — each offer curated sets of hooks, but they take different approaches in design, scope, and developer experience. Let’s compare them through real-world engineering lenses.

đź§© Philosophy and Scope: Minimalism vs Completeness vs Breadth

@uidotdev/usehooks focuses on clarity and education. Each hook is small, well-documented, and often accompanied by live examples. It avoids complex abstractions and sticks to solving one problem per hook.

// @uidotdev/usehooks: simple, readable implementation
import { useLocalStorage } from '@uidotdev/usehooks';

function MyComponent() {
  const [name, setName] = useLocalStorage('name', 'Anonymous');
  return <input value={name} onChange={e => setName(e.target.value)} />;
}

ahooks emphasizes robustness and type safety, especially in large-scale applications. It includes advanced features like request cancellation, debouncing control, and detailed loading states — all with strong TypeScript definitions.

// ahooks: rich options and precise typing
import { useRequest } from 'ahooks';

function UserProfile({ id }: { id: string }) {
  const { data, loading, error } = useRequest(() => fetchUser(id), {
    manual: false,
    debounceWait: 300,
  });
  // data is strongly typed based on fetchUser's return type
}

react-use offers the widest variety of hooks — over 100 — including many for niche browser APIs (like useBattery, useSpeechRecognition). Some hooks are more experimental, and the API can feel less consistent across the library.

// react-use: broad coverage, including uncommon APIs
import { useClickAway, useMedia } from 'react-use';

function Modal() {
  const ref = useRef();
  const isMobile = useMedia('(max-width: 768px)');
  useClickAway(ref, () => closeModal());
  return <div ref={ref}>{isMobile ? 'Mobile View' : 'Desktop View'}</div>;
}

🔌 State Management: Local Persistence Patterns

All three provide hooks for localStorage, but their APIs differ in flexibility and error handling.

@uidotdev/usehooks keeps it simple: just get and set.

import { useLocalStorage } from '@uidotdev/usehooks';
const [value, setValue] = useLocalStorage('key', 'default');

ahooks gives you full control, including serialization customization and error callbacks.

import { useLocalStorageState } from 'ahooks';

const [value, setValue] = useLocalStorageState('key', {
  defaultValue: 'default',
  serializer: v => JSON.stringify(v),
  deserializer: v => JSON.parse(v!),
});

react-use uses a similar simple signature but supports functional updates.

import { useLocalStorage } from 'react-use';
const [value, setValue] = useLocalStorage('key', 'default');
// setValue(prev => prev + ' updated') works

📡 Data Fetching: From Basic to Enterprise-Grade

@uidotdev/usehooks does not include a dedicated data-fetching hook. You’d typically pair it with fetch + useEffect or a separate library like SWR.

ahooks provides useRequest — a powerful, SWR-inspired hook with built-in polling, retry, pagination, and cache management.

const { data, loading, run } = useRequest(getData, {
  pollingInterval: 5000,
  ready: !!userId, // only run when userId exists
});

react-use includes basic fetching via useAsync, but it’s minimal and lacks advanced features like caching or deduplication.

import { useAsync } from 'react-use';
const { value, loading } = useAsync(() => fetchData(), []);

For serious data requirements, ahooks stands out; the others expect you to bring your own solution.

⏱️ Timing and Side Effects: Debounce, Throttle, and Delays

All three handle timing utilities, but with different ergonomics.

@uidotdev/usehooks offers useDebounce that returns a debounced value:

const debouncedSearch = useDebounce(searchTerm, 500);
useEffect(() => {
  if (debouncedSearch) performSearch(debouncedSearch);
}, [debouncedSearch]);

ahooks provides useDebounceFn, which returns a debounced function you can call directly:

const { run: debouncedSearch } = useDebounceFn(
  (term) => performSearch(term),
  { wait: 500 }
);
// Call debouncedSearch(term) in onChange

react-use also uses the function-returning pattern:

const debounced = useDebounce(() => performSearch(searchTerm), 500);
// But note: this creates a new debounced fn on every render unless memoized

ahooks’s approach is more predictable in component re-renders due to stable function identity and explicit control.

đź§Ş TypeScript Support: From Optional to First-Class

@uidotdev/usehooks ships with TypeScript types, but they’re basic and inferred rather than explicitly designed.

ahooks is built with TypeScript from the ground up. Every hook has precise generics, and the library enforces strict type contracts (e.g., useRequest infers response type from the async function).

react-use has TypeScript support, but some hooks have loose or any-typed internals, requiring more manual type assertion in complex scenarios.

If your team relies heavily on TypeScript for correctness, ahooks provides the strongest guarantees.

đź§° Real-World Trade-Offs

When to pick @uidotdev/usehooks

  • You want zero-config, copy-paste-friendly hooks.
  • Your app is small-to-medium and doesn’t need advanced data fetching.
  • You prioritize learning and readability over feature density.

When to pick ahooks

  • You’re in a TypeScript-first environment with strict quality requirements.
  • You need production-grade data fetching with retry, cache, and loading states.
  • Your team already uses Ant Design or other Alibaba tech (natural ecosystem fit).

When to pick react-use

  • You need a hook for an obscure browser API (e.g., useNetwork, useGeolocation).
  • You’re prototyping quickly and want a “grab-and-go” utility.
  • You don’t mind occasionally checking source code to understand behavior.

🔄 Similarities: Shared Foundations

Despite differences, all three libraries:

  1. Follow React’s rules of hooks and avoid anti-patterns.
  2. Handle cleanup automatically (e.g., removing event listeners on unmount).
  3. Support server-side rendering safely (no direct window access in render phase).
  4. Are actively maintained as of 2024, with no deprecation notices.

Example of safe SSR-compatible hook usage across all three:

// All libraries avoid accessing window during render
// They use useEffect or lazy initialization internally
const width = useWindowSize().width; // works in SSR without crashing

📊 Summary Table

Feature@uidotdev/usehooksahooksreact-use
PhilosophySimple, educationalRobust, enterprise-readyBroad, experimental
TypeScript QualityBasicExcellentModerate
Data FetchingNot includedFull-featured (useRequest)Minimal (useAsync)
Hook Count~20~80~100+
API ConsistencyHighVery highModerate
Best ForLearning, small appsLarge apps, TypeScriptPrototyping, niche APIs

đź’ˇ Final Thought

These libraries aren’t mutually exclusive — you could even mix them selectively. But for architectural consistency, choose one based on your team’s priorities: simplicity (@uidotdev/usehooks), reliability (ahooks), or breadth (react-use). In most professional settings where maintainability and type safety matter, ahooks tends to offer the best balance of power and predictability.

How to Choose: react-use vs @uidotdev/usehooks vs ahooks

  • react-use:

    Choose react-use if you need the broadest collection of utility hooks covering diverse browser APIs and edge cases, and you’re comfortable with a more experimental or flexible API style. It works well for rapid prototyping or projects that require niche functionality not found in smaller libraries, though you may need to verify stability for mission-critical features.

  • @uidotdev/usehooks:

    Choose @uidotdev/usehooks if you value minimal, focused hooks with clear documentation and educational examples. It’s ideal for teams that prefer lightweight utilities without complex configuration or opinionated patterns, especially when building straightforward applications where simplicity and readability are prioritized over advanced features.

  • ahooks:

    Choose ahooks if you're working in a TypeScript-heavy codebase and need robust, production-ready hooks with strong type safety and comprehensive lifecycle management. It’s particularly well-suited for enterprise applications built with Ant Design or other Alibaba ecosystem tools, where consistency, reliability, and deep integration with modern React patterns are critical.

README for react-use



👍
react-use





npm package CircleCI master npm downloads demos
Collection of essential React Hooks. Port of libreact.
Translations: 🇨🇳 汉语




npm i react-use












Usage — how to import.
Unlicense — public domain.
Support — add yourself to backer list below.






Contributors