React useLocalStorage Hook
React useLocalStorage hook for persistent state. Automatic serialization with cross-tab synchronization and SSR support using TypeScript for Next.js apps.
localStorage hook not working?
Join our Discord community for help from other developers.
Ever tried to persist user preferences across page reloads and ended up wrestling with localStorage APIs, JSON serialization bugs, and cross-tab sync issues? You know the drill—manually saving to localStorage on every state change, forgetting to parse JSON back to objects, dealing with storage quota errors. This free open source React useLocalStorage custom hook handles all that persistence complexity so you can focus on building stateful features instead of debugging storage edge cases in your React applications.
useLocalStorage showcase
Persistent state that survives page reloads and syncs across tabs:
This free open source React hook simplifies browser storage with TypeScript support for modern JavaScript applications. Whether you're building user preferences, form drafts, or session data in your Next.js projects, this React hook keeps your state persistent and synchronized.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/use-local-storage.json
npx shadcn@latest add https://www.shadcn.io/registry/use-local-storage.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-local-storage.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-local-storage.json
Why most localStorage implementations suck
Look, you could keep calling localStorage.setItem and JSON.stringify everywhere. But then you hit the storage complexity—serialization errors with undefined values, quota exceeded exceptions, cross-tab synchronization headaches, SSR hydration mismatches in React applications.
Most developers manually manage localStorage calls with fragmented try-catch blocks that don't handle all edge cases in TypeScript components. Or they forget about cross-tab synchronization and wonder why user changes in one tab don't appear in others. Some skip SSR considerations entirely and get hydration mismatches with flashing content in Next.js projects.
This React hook provides a useState-like API that automatically handles serialization, error recovery, and cross-tab updates in JavaScript applications. One interface for all your localStorage needs.
Plus it handles all the edge cases—graceful fallbacks when localStorage is disabled, proper SSR initialization, automatic event listening for cross-tab sync in React development. No more scattered try-catch blocks.
This free open source React hook manages persistent storage while you focus on building features. Whether you're creating React applications, Next.js dashboards, or TypeScript components, reliable state persistence keeps your JavaScript development smooth.
Features
- Persistent state that survives page reloads and browser sessions in React applications
- Automatic serialization with JSON serialization/deserialization by default in TypeScript components
- Cross-tab synchronization syncs changes across browser tabs automatically in Next.js projects
- Custom serializers support for dates, complex objects, and custom types in JavaScript development
- SSR compatible with optional initialization for server-side rendering in React frameworks
- Type safety with full TypeScript support and proper generics for modern applications
- Error handling with graceful fallbacks for localStorage errors
- Free open source designed for modern React development workflows
When you'll actually use this
Real talk—this isn't for every piece of state in React applications. Regular useState works fine for temporary UI state. But when you need data to persist across sessions or sync across tabs, this React hook handles the complexity in Next.js projects.
Perfect for:
- User preferences - Theme settings, language choices, and UI configurations built with TypeScript
- Form drafts - Save progress on long forms to prevent data loss using React patterns
- Shopping carts - Persist cart items across browser sessions in JavaScript applications
- Session data - User settings and temporary data that should survive refreshes in React components
- Feature flags - Client-side toggles that persist across visits in Next.js applications
- Recently viewed - Track user interactions and browsing history using TypeScript safety
API Reference
useLocalStorage
useLocalStorage<T>(key: string, initialValue: T | (() => T), options?: UseLocalStorageOptions<T>): [T, (value: T | ((prev: T) => T)) => void, () => void]
Parameter | Type | Description |
---|---|---|
key | string | The key under which the value will be stored in localStorage |
initialValue | T | (() => T) | The initial value or a function that returns the initial value |
options | UseLocalStorageOptions<T> | Optional configuration for serialization and behavior |
UseLocalStorageOptions
Property | Type | Default | Description |
---|---|---|---|
serializer | (value: T) => string | JSON.stringify | Function to serialize the value before storing |
deserializer | (value: string) => T | JSON.parse | Function to deserialize the stored value |
initializeWithValue | boolean | true | Whether to initialize with stored value (set to false for SSR) |
Return Value
Returns a tuple with:
value
: The current stored valuesetValue
: Function to update the value (same API asuseState
)removeValue
: Function to remove the key from localStorage and reset to initial value
Common gotchas
Storage quota limits apply: Browsers limit localStorage size (usually 5-10MB) in React applications. The React hook handles quota exceeded errors gracefully but won't prevent them.
Cross-tab sync has slight delays: Storage events fire when other tabs change values, but there's a small delay in TypeScript components. Don't rely on instant synchronization.
SSR requires careful initialization: Use initializeWithValue: false
for SSR to prevent hydration mismatches in Next.js projects, then handle the loading state appropriately.
JSON serialization has limitations: Dates become strings, undefined values are dropped, functions can't be serialized in JavaScript applications. Use custom serializers for complex types.
Storage availability checks: Always handle cases where localStorage might be disabled by browser settings or privacy mode in React frameworks.
Key naming consistency: Use consistent key naming patterns across your application to avoid conflicts and enable easier debugging in TypeScript projects.
Related hooks you will also like
useDarkMode
Dark mode state that relies on localStorage for persistence
useBoolean
Boolean state management that pairs well with persistent toggles
useCounter
Counter state that can be persisted across sessions
useIsClient
Client detection needed for safe localStorage access
useDebounceValue
Debounce localStorage updates to prevent excessive writes
useToggle
Toggle state management with optional persistence
Questions you might have
React useIsomorphicLayout Hook
React useIsomorphicLayoutEffect hook for SSR-safe layout effects. Prevent hydration warnings while maintaining synchronous DOM access with TypeScript.
React useMap Hook
React useMap hook for Map state management. Type-safe key-value operations with immutable updates and performance optimization using TypeScript for Next.js.