Skip to content
D
Documentation

Persisted state lifecycle

concept
1 min readUpdated

Persistence adds a storage read and write around a Zustand store: the middleware saves selected state when it changes, then hydrates the store from saved values during initialization.

How state moves through persistence

persist wraps the store's state creator. On initialization, it reads the item identified by name, checks its version, optionally migrates it, and merges the stored state with the store's current state. When the store changes, it applies partialize and writes that state and the version to storage.

mermaid
flowchart LR
  A["Initial state creator"] --> B["persist reads storage by name"]
  B --> C{"Stored version matches?"}
  C -->|"No; migrate is configured"| D["migrate stored state"]
  C -->|"Yes, or no stored value"| E["Stored state (possibly absent)"]
  D --> F["merge with current state"]
  E --> F
  F --> G["Hydrated store"]
  G --> H["State update"]
  H --> I["partialize, then write to storage"]

The stored value has a state and an optional version field (StorageValue). The default storage uses JSON and localStorage; the default merge is shallow, with stored top-level fields taking precedence over the current state's fields. If no stored value exists, the current state remains in place.

Combining and evolving stored state

  • The default merge is shallow. If you persist a nested object but omit some of its fields, the stored nested object replaces the current nested object at that top-level key. Provide a custom merge when rehydration must preserve or combine nested fields.
  • Use version and migrate when a change makes stored data incompatible with the current state shape. A version mismatch without a migration leaves the stored value unused; a migration returns the state for the current version.
  • skipHydration prevents the initial automatic hydration. This lets an application control when to call rehydrate(), such as in a server-rendered application.
  • onRehydrateStorage provides a callback before hydration and an optional callback after hydration or an error.

For the storage setup and partial-persistence examples, see Persist state to storage.

Was this page helpful?

Persisted state lifecycle — zustand · GPT-6 Luna