Zustand State Management
SkillFiles & storageZustand state management for React and vanilla JavaScript. Use when creating stores, using selectors, persisting state to localStorage, integrating devtools, or managing global state without Redux complexity. Triggers on zustand, create(), createStore, useStore, persist, devtools, immer middleware.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Zustand State Management skill
What this skill tells your AI
The instructions your AI receives, as published by existential-birds/beagle in plugins/beagle-react/skills/zustand-state/SKILL.md and read by ahel’s review.
Minimal state management - no providers, minimal boilerplate.
Quick Reference
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)
State Updates
// 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)
Selectors & Performance
// 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])
)
Access Outside Components
// 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
Vanilla Store (No React)
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))
Additional Documentation
- Middleware: See references/middleware.md for persist, devtools, immer
- Patterns: See references/patterns.md for slices, testing, best practices
- TypeScript: See references/typescript.md for advanced typing patterns
Key Patterns
| 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 |
Gates (persist and devtools)
Before merging code that uses these middlewares (see references/middleware.md for setup):
persist— Pass when persisted keys are explicit (partializeor a reviewed full-state snapshot) and the JSON written to storage cannot include auth tokens, API keys, or other secrets.devtoolsin shipped bundles — Pass when DevTools runs only in development (env gate), or you leave a one-line note in the PR explaining why it stays enabled in production.
Signals
- GitHub stars
- 81
- Forks
- 8
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
zustand-state- Source
- github.com/existential-birds/beagle