Comparing
Create your next immutable state by mutating the current one
Hooks for managing, caching and syncing asynchronous and remote data in React
| Metric | immer | react-query |
|---|---|---|
| Ecosystem | npm | npm |
| Difficulty | Beginner | Beginner |
| Weekly downloads | 41.7M↑ | 1.6M |
| Latest version | v11.1.4 | v3.39.3 |
| Recipes | 1 | 1 |
immer only
Shared
react-query only
Use Immer whenever you have deeply nested state updates that are painful to write immutably: Redux reducers, Zustand's set function, or React useState with complex objects. It's built into Redux Toolkit's createSlice, so you're probably already using it.
Use React Query for any React app that fetches server data: REST APIs, GraphQL, or any async function. It replaces 95% of the useEffect+useState patterns for data fetching and adds caching, background refetching, and optimistic updates for free.
For flat, simple state (a counter, a boolean toggle), immer's overhead isn't worth it — just spread the object. Immer also has edge cases with classes, Maps, and Sets that require using enableMapSet() and enableAllPlugins().
React Query is for server state (data that lives on a server). For UI state (modals, form values, local toggles), use useState or Zustand. If you're already using a full data layer like Apollo Client for GraphQL, React Query is redundant.
immer
react-query