How to Persist State

Persisting your Valtio state to a storage medium like localStorage is straightforward, especially if your state is JSON serializable.

Basic Persistence with localStorage

The core idea is to:

  1. Initialize the state from localStorage on application load.
  2. Subscribe to the state and save it to localStorage on every change.
import { proxy, subscribe } from 'valtio/vanilla';

// 1. Load the initial state from localStorage, or use a default.
const initialState = JSON.parse(localStorage.getItem('myAppState')) || {
  count: 0,
  text: 'hello',
};

const state = proxy(initialState);

// 2. Subscribe to changes and save to localStorage.
subscribe(state, () => {
  localStorage.setItem('myAppState', JSON.stringify(state));
});

Handling Non-Serializable Values

If your state contains non-serializable values (like functions, Maps, Sets, or objects wrapped in ref), you'll need to handle them manually. The strategy is to:

  1. Exclude non-serializable properties before saving.
  2. Re-attach them after loading the state from storage.
// ...
const state = proxy({
  // serializable data
  count: 0,
  // non-serializable data
  onUpdate: ref(() => console.log('updated')),
});

subscribe(state, () => {
  const stateToSave = { ...state };
  delete stateToSave.onUpdate; // Exclude the function
  localStorage.setItem('myAppState', JSON.stringify(stateToSave));
});

Using valtio-persist

For a more robust and flexible solution, consider using the community library valtio-persist. It automates the process of saving and loading state and handles many edge cases for you.