New:Socket for Asana Is Now Available.Learn more
Get Started

@guoyunhe/react-storage

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@guoyunhe/react-storage

React hooks for localStorage and sessionStorage with JSON serialization, custom serializer/parser, key prefix, and SSR-safe fallback

latest
Source
npmnpm
Version
2.0.3
Version published
Weekly downloads
88
60%
Maintainers
1
Weekly downloads
 
Created
Source

@guoyunhe/react-storage

npm version npm downloads bundle size socket security license

React hooks for localStorage and sessionStorage — JSON serialization, custom serializer/parser, key prefix namespacing, and real-time cross-tab sync. SSR-safe with zero direct dependencies.

Features

  • 🪝 useState-like API — drop-in replacement with the same [value, setValue] tuple
  • 🔄 Cross-tab sync — state stays in sync across browser tabs via the native storage event
  • 🧩 Custom serializer/parser — store Date, Map, or any custom type
  • 📦 JSON by default — objects and arrays work out of the box
  • 🏷️ Key prefix — namespace storage keys per app via <StorageProvider>
  • 🌐 SSR-safe — no window access during render, works with Next.js and Remix
  • 🪶 Tiny bundle — zero runtime dependencies, tree-shakable ESM
  • 💪 TypeScript first — fully typed with generics

Install

npm install --save @guoyunhe/react-storage

Quick Start

import { useLocalStorage, useSessionStorage } from '@guoyunhe/react-storage';

function App() {
  const [settings, setSettings] = useLocalStorage('settings', {
    theme: 'dark',
    fontSize: 14,
  });

  const [draft, setDraft] = useSessionStorage('draft', '');
}

Guides

Custom types (Date, Map, etc.)

Use serializer and parser to handle non-JSON types:

const [date, setDate] = useLocalStorage('date', new Date(), {
  serializer: (d) => d.toISOString(),
  parser: (s) => new Date(s),
});

Key prefix for multi-app domains

Scope storage keys per app to avoid collisions:

import { StorageProvider, useLocalStorage } from '@guoyunhe/react-storage';

function App() {
  return (
    <StorageProvider prefix='dashboard_'>
      <Dashboard />
    </StorageProvider>
  );
}

function Dashboard() {
  // actual key: "dashboard_theme"
  const [theme, setTheme] = useLocalStorage('theme', 'light');
}

Global serializer/parser

Set defaults once at the top level:

<StorageProvider serializer={mySerializer} parser={myParser} prefix='app_'>
  <App />
</StorageProvider>

Cross-tab counter

All components reading the same key stay in sync — even across tabs:

function Counter() {
  const [count, setCount] = useLocalStorage('count', 0);

  return (
    <div>
      <button onClick={() => setCount((c) => c - 1)}>−</button>
      <span>{count}</span>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
    </div>
  );
}

// Render multiple <Counter /> — they all share the same state

API

useLocalStorage<T>(key, defaultValue, options?)

Returns [value, setValue] — same shape as useState. Values persist in localStorage and sync across tabs.

useSessionStorage<T>(key, defaultValue, options?)

Same API as useLocalStorage, but stores in sessionStorage. Data is cleared when the tab closes. Useful for draft forms, wizard state, and ephemeral UI state.

options

OptionTypeDefaultDescription
serializer(value: T) => stringJSON.stringifyCustom serialize function
parser(raw: string) => TJSON.parseCustom parse function
prefixstring''Override the global prefix for this key

<StorageProvider>

Provides global defaults for all hooks within its subtree.

PropTypeDefaultDescription
serializer(value: any) => stringJSON.stringifyGlobal serializer
parser(raw: string) => anyJSON.parseGlobal parser
prefixstring''Global key prefix

Comparison

@guoyunhe/react-storageuse-local-storage-stateusehooks-tsreact-useahooks
React peer>=16.8>=18>=16.8*>=16.8
Dependencies0011410
Local + Session
Cross-tab sync
Key prefix
Custom serializer
Typed API
ESM

License

MIT

Keywords

browser

FAQs

Package last updated on 27 Aug 2026

Related posts