Help us improve
Share bugs, ideas, or general feedback.
From beagle-react
Guides Zustand state management in React and vanilla JS: stores, selectors, persistence, devtools, performance patterns, and non-React access.
npx claudepluginhub existential-birds/beagle --plugin beagle-reactHow this skill is triggered — by the user, by Claude, or both
Slash command
/beagle-react:zustand-stateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Minimal state management - no providers, minimal boilerplate.
Creates and manages Zustand stores for React state management, covering creation, selectors, actions, updates, and performance best practices like shallow equality.
Creates lightweight global stores with Zustand's create function for minimal-boilerplate React state management. Use for auth, UI flags, preferences without prop drilling or Redux complexity.
Provides Zustand 5.x patterns for React state management: slices, middleware, Immer, useShallow, persistence, selectors, devtools, async actions, and anti-patterns with TanStack Query integration. Use for global client state without boilerplate.
Share bugs, ideas, or general feedback.
Minimal state management - no providers, minimal boilerplate.
import { create } from 'zustand'
interface BearState {
bears: number
increase: (by: number) => void
}
const useBearStore = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}))
// In component - select only what you need
const bears = useBearStore((state) => state.bears)
const increase = useBearStore((state) => state.increase)
// Flat updates (auto-merged at one level)
set({ bears: 5 })
set((state) => ({ bears: state.bears + 1 }))
// Nested objects (manual spread required)
set((state) => ({
nested: { ...state.nested, count: state.nested.count + 1 }
}))
// Replace entire state (no merge)
set({ bears: 0 }, true)
// Good - subscribes only to bears
const bears = useBearStore((state) => state.bears)
// Bad - rerenders on any change
const state = useBearStore()
// Multiple values with useShallow (prevents rerenders with shallow comparison)
import { useShallow } from 'zustand/react/shallow'
const { bears, fish } = useBearStore(
useShallow((state) => ({ bears: state.bears, fish: state.fish }))
)
// Array destructuring also works
const [bears, fish] = useBearStore(
useShallow((state) => [state.bears, state.fish])
)
// Get current state (non-reactive)
const state = useBearStore.getState()
// Update state
useBearStore.setState({ bears: 5 })
// Subscribe to changes
const unsub = useBearStore.subscribe((state) => console.log(state))
unsub() // unsubscribe
import { createStore } from 'zustand/vanilla'
const store = createStore((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}))
store.getState().bears
store.setState({ bears: 10 })
store.subscribe((state) => console.log(state))
| Pattern | When to Use |
|---|---|
| Single selector | One piece of state needed |
useShallow | Multiple values, avoid rerenders |
getState() | Outside React, event handlers |
subscribe() | External systems, logging |
| Vanilla store | Non-React environments |