Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Zustand · Pipe

storage

The persist middleware saves Zustand state across page reloads or application restarts. Configure a unique storage key and optionally provide a custom storage adapter.

How it works

The persist middleware wraps a Zustand state creator and stores its state under a unique name. A storage adapter can be supplied explicitly; createJSONStorage converts a storage implementation such as localStorage into the format persist expects, and its lazy getter avoids accessing browser storage during module evaluation.

Syntax

persist(stateCreatorFn, persistOptions)

Parameters

NameTypeDescription
stateCreatorFnStateCreatorState creator function receiving set, get, and store; it returns the store state and actions.
persistOptionsPersistOptionsConfiguration object for persistence.
namestringUnique storage key for the persisted store.
storagePersistStorageOptional PersistStorage adapter; defaults to createJSONStorage(() => localStorage).

Returns

A Zustand store enhanced with persistence and hydration behavior.

Key points

  • Wrap a state creator with persist to retain store data after a page reload or application restart.
  • Without a custom adapter, persist uses JSON serialization over localStorage.
  • The persist options object configures how and where the state is stored.

Common mistakes

  • Create the storage through createJSONStorage rather than reading localStorage while the module is evaluated, especially in SSR environments.

Example: Persist state with custom storage

import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

const usePositionStore = create(
  persist(
    (set) => ({
      position: { x: 0, y: 0 },
      setPosition: (position) => set({ position }),
    }),
    {
      name: 'position-storage',
      storage: createJSONStorage(() => localStorage),
    },
  ),
)

usePositionStore.getState().setPosition({ x: 10, y: 20 })

Creates a store whose position state is serialized to localStorage and restored after a reload.

When to use it

Keep user preferences or UI position after reloads using localStorage.

Browser applications

Persist state with an asynchronous adapter such as AsyncStorage.

React Native applications

Store state in URL search parameters through a custom storage adapter.

URL-driven interfaces

Defer browser storage access with createJSONStorage to avoid module-evaluation errors.

Server-rendered applications

Interview questions

QWhat problem does the persist middleware solve?

persist wraps a state creator and saves the selected store data in a storage backend across reloads or restarts. The required name option identifies the stored item, while storage selects the adapter and defaults to JSON-backed localStorage.

Follow-up: How would you support a nonstandard backend? Supply a storage object, commonly produced with createJSONStorage, whose getter returns the desired storage implementation.

QWhy use createJSONStorage?

createJSONStorage accepts a function that returns a storage implementation and creates a compatible storage object. The function is evaluated lazily, so browser-only APIs are not accessed during module evaluation.

Follow-up: Why does that matter for SSR? Server execution may not provide localStorage, so deferred access prevents module-evaluation failures.

QHow does hydration differ for synchronous and asynchronous storage?

Hydration retrieves persisted state and merges it with the current state. Synchronous storage hydrates during store creation, whereas asynchronous storage hydrates later in a microtask.

Follow-up: What design concern follows from asynchronous hydration? UI or actions that depend on restored values may need to wait until hydration has completed.

  • createJSONStorage
  • PersistStorage
  • StateStorage
  • rehydrate
  • persisting store data
  • localStorage
  • AsyncStorage

Source: persist middleware. Checked 2026-10-15.