Zustand is a minimal state library. A store is a hook; components subscribe to just the slice they use.
Core concepts
- Create a store: Call
createwith a function that returns state and actions. Components call the hook to read state or actions. — Zustand docs - Selectors: Select only what a component needs, for example
useCart((s) => s.ids.length), so unrelated changes do not re-render it. — Zustand docs - Persist middleware: Persist selected state to AsyncStorage or MMKV with
persistandcreateJSONStorage, and use aversionplusmigratewhen the shape changes. — Zustand persist - Keep stores small: One store per concern (auth session, filters, cart). Avoid a single store for the whole app. — Zustand docs
Concept videos
YouTube channels and searches for these topics. On a large screen they open in the reading panel next to the roadmap.
- Zustand tutorials — YouTube search: Zustand React Native persist AsyncStorage
Explanation
Migrations matter
If you rename a persisted field, old installs load the old shape and crash. Use the persist version and a migrate function.
Secrets do not belong here
Persisted Zustand state is plain storage. Store tokens in SecureStore, not in a persisted store.
What Is It?
Zustand is a small library for shared client-side state using hooks.
Why Should I Care?
It is simple enough for agents to use correctly and avoids the boilerplate of larger libraries.
Real World Analogy
A Zustand store is a shared whiteboard with named sections; each reader only looks at their section.
Visual Mental Model
create(store) -> useStore(selector) -> component re-renders only on that sliceSmallest Possible Example
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
export const useSettings = create(
persist<{ dark: boolean; toggle: () => void }>(
(set) => ({ dark: false, toggle: () => set((s) => ({ dark: !s.dark })) }),
{ name: 'settings', storage: createJSONStorage(() => AsyncStorage), version: 1 }
)
);Common Mistakes
❌ Selecting the whole store in every component.
That re-renders on any change; select slices.
❌ Persisting tokens in a normal store.
Use SecureStore for secrets.
Build This Mini Project
Create a persisted settings store with a version and a migrate function, and a screen that toggles theme.
Prompts for Cursor, Claude Code & Codex
Paste these into Cursor, Claude Code, Codex, or any coding agent. Replace the bracketed parts with your app details, and keep the agent in plan mode first so you review the approach before it edits files.
Add persisted store
Create lib/stores/settings.ts with Zustand and persist (AsyncStorage). Include version 1 and a migrate stub, and selectors in the settings screen. Do not store secrets.Rules, databases & blogs to use
- Zustand rule: Zustand conventions

