Search

PythonReactSEOPDF
GitHub Skill

zustand

Zustand 5+ state management. Use when creating stores, selectors, middleware, or persisting state.

tirtza-weinfeld☆ 0 Repository stars0 Repository forks

Installation

Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.

View source ↗Guides

Skill instructions

Zustand 5+

Create store — named import

import { create } from 'zustand'

const useStore = create<State>()((set, get) => ({
  count: 0,
  inc: () => set((s) => ({ count: s.count + 1 })),
  reset: () => set({ count: 0 })
}))

// NOT default import — that's v4

Selectors with useShallow

import { useShallow } from 'zustand/shallow'

// Single value — no useShallow needed
const count = useStore((s) => s.count)

// Multiple values — use useShallow to prevent re-renders
const { name, email } = useStore(
  useShallow((s) => ({ name: s.name, email: s.email }))
)

// NOT custom equality in create() — that's v4

Custom equality (if needed)

import { createWithEqualityFn } from 'zustand/traditional'
import { shallow } from 'zustand/shallow'

const useStore = createWithEqualityFn<State>()(
  (set) => ({ ... }),
  shallow
)

// NOT create(fn, shallow) — that's v4

Persist middleware

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

const useStore = create<State>()(
  persist(
    (set) => ({
      theme: 'dark',
      setTheme: (t) => set({ theme: t })
    }),
    { name: 'app-storage' }
  )
)

// v5: Initial state NOT auto-persisted on creation
// Hydration happens async — handle loading state

Persist with partialize

persist(
  (set) => ({ ... }),
  {
    name: 'app-storage',
    partialize: (state) => ({ theme: state.theme })  // only persist theme
  }
)

setState with replace

// Partial update (default)
set({ count: 5 })

// Full replace — must provide complete state
set({ count: 5, name: 'New', items: [] }, true)

// v5: replace=true requires ALL fields

Combine middleware

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

const useStore = create<State>()(
  devtools(
    persist(
      (set) => ({ ... }),
      { name: 'storage' }
    ),
    { name: 'MyStore' }
  )
)

Access outside React

// Get current state
const count = useStore.getState().count

// Subscribe to changes
const unsub = useStore.subscribe((state) => console.log(state))

// Set state directly
useStore.setState({ count: 10 })

Slices pattern

const createUserSlice = (set) => ({
  user: null,
  setUser: (user) => set({ user })
})

const createCartSlice = (set) => ({
  items: [],
  addItem: (item) => set((s) => ({ items: [...s.items, item] }))
})

const useStore = create((...a) => ({
  ...createUserSlice(...a),
  ...createCartSlice(...a)
}))

Avoid

  • Default import → named import { create }
  • create(fn, shallow) → createWithEqualityFn from zustand/traditional
  • Object selector without useShallow → causes re-renders
  • setState({}, true) → replace requires complete state
  • Assuming persist hydrates sync → handle loading state

Examples

Read the usage examples in the source repository.

View source ↗

Source history

Indexed on
2026-01-20
Index updated
2026-03-03
Branch
main

Index and sync dates describe this directory. View the source repository for code history.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!