# use-cached

> React hook for caching states in localStorage with TTL/expiration support

Latest version **3.0.1** (published 2026-05-15) · MIT license · 0 weekly downloads

## Install

```sh
npm install use-cached
pnpm add use-cached
yarn add use-cached
bun add use-cached
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.0.1 |
| Published | 2026-05-15 |
| First published | 2019-03-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 9.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 5 |
| Author | woozyking |
| Maintainers | woozyking |
| Keywords | react, hook, cache, localstorage |

## Links

- npm: https://www.npmjs.com/package/use-cached
- Repository: https://github.com/woozyking/use-cached
- Homepage: https://github.com/woozyking/use-cached#readme
- Issues: https://github.com/woozyking/use-cached/issues
- npm.io page: https://npm.io/package/use-cached

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 3.0.1 (latest) — 2026-05-15
- 1.2.1-alpha2 (alpha) — 2020-05-08
- 1.2.1-alpha (true) — 2020-05-07
- 3.0.0 — 2026-05-12
- 2.0.0 — 2020-08-06
- 1.2.1 — 2020-05-08
- 1.2.0 — 2020-05-07
- 1.1.1-alpha — 2019-09-19
- 1.1.0 — 2019-07-16
- 1.1.0-alpha — 2019-07-16
- 1.0.1 — 2019-03-31
- 1.0.0 — 2019-03-30
- 0.3.2-alpha — 2019-03-27
- 0.3.1-alpha — 2019-03-27
- 0.3.0-alpha — 2019-03-27
- … 2 more at https://npm.io/package/use-cached/versions

## README

# use-cached

[![NPM Version](https://img.shields.io/npm/v/use-cached)](https://www.npmjs.com/package/use-cached)

A zero-dependency, highly performant higher-order function that bakes `localStorage` caching and optional TTL (Time To Live) expiration into standard React hooks (`useState` and `useReducer`).

## Features

- **Zero Dependencies:** Fully natively manages `localStorage`. No external caching libraries required.
- **High Performance:** Uses React's lazy initialization to ensure `localStorage` (a synchronous, blocking API) is only read exactly once during component mount, preventing render bottlenecks.
- **TTL Expiration:** Easily set cache expiration times so your state doesn't get stale permanently.
- **Cache Invalidation:** The wrapped hooks return a 3rd tuple element—a dedicated removal function to easily wipe the cache for that specific key.

## Install

```shell
npm install use-cached
```

Or the equivalent of your choice of package manager.

## API Configuration

The `cached` function accepts a configuration object to define how the state is stored:

* **`key`** *(string, required)*: The unique `localStorage` key used to save the data.
* **`ttl`** *(number, optional)*: Time To Live multiplier. How long the cache is valid. If not provided, the cache will never expire.
* **`ttlMS`** *(number, optional)*: The base unit in milliseconds for the `ttl`. Default is `60000` (1 minute).

*Example: `ttl: 5` and `ttlMS: 1000` means the cache expires in 5000 milliseconds (5 seconds).*

## Usage Examples

### 1. Basic `useState`

When wrapping `useState`, the hook returns `[state, setState, removeCache]`.

```jsx
import { useState } from "react";
import { cached } from "use-cached";

const useCachedState = cached({ key: "app_user_name" })(useState);

function BasicStateDemo() {
  const [name, setName, removeCache] = useCachedState("Guest");

  return (
    <>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button onClick={removeCache}>Clear Cache</button>
    </>
  );
}
```

### 2. `useState` with TTL Expiration

```jsx
import { useState } from "react";
import { cached } from "use-cached";

// Expires in 5 seconds (ttl: 5, ttlMS: 1000ms)
const useExpiringState = cached({
  key: "app_temp_count",
  ttl: 5,
  ttlMS: 1000,
})(useState);

function ExpiringCounter() {
  const [count, setCount] = useExpiringState(0);

  return (
    <button onClick={() => setCount((c) => c + 1)}>
      Increment: {count}
    </button>
  );
}
```

### 3. Cached `useReducer`

When wrapping `useReducer`, the hook returns `[state, dispatch, removeCache]`.

```jsx
import { useReducer } from "react";
import { cached } from "use-cached";

const useCachedReducer = cached({ key: "app_counter_reducer" })(useReducer);

const counterReducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT': return { count: state.count + 1 };
    case 'DECREMENT': return { count: state.count - 1 };
    case 'RESET': return { count: 0 };
    default: return state;
  }
};

function ReducerDemo() {
  const [state, dispatch, removeCache] = useCachedReducer(counterReducer, { count: 0 });

  return (
    <>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
      <button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
      <button onClick={removeCache}>Clear Cache</button>
    </>
  );
}
```

---
_Source: https://npm.io/package/use-cached · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
