zustand-5
Guides the implementation of state management in client-side apps using Zustand 5 features.
Install
mkdir -p .claude/skills/zustand-5 && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/1473" && unzip -o skill.zip -d .claude/skills/zustand-5 && rm skill.zipInstalls to .claude/skills/zustand-5
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Zustand 5 state management patterns. Trigger: When implementing client-side state with Zustand (stores, selectors, persist middleware, slices).Key capabilities
- →Generates boilerplate stores using Zustand 5 primitives
- →Optimizes state selection to minimize re-renders
- →Implements persistent state via built-in middleware
- →Refactors logic into modular state slices
How it works
It applies standard store initialization patterns and middleware configurations to ensure efficient state updates through selector-based subscription.
Inputs & outputs
When to use zustand-5
- →Creating a new Zustand store
- →Implementing state persistence
- →Optimizing selectors for re-renders
- →Refactoring state logic into slices
About this skill
Basic Store
import { create } from "zustand";
interface CounterStore {
count: number;
increment: () => void;
decrement: () => void;
reset: () => void;
}
const useCounterStore = create<CounterStore>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// Usage
function Counter() {
const { count, increment, decrement } = useCounterStore();
return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
Persist Middleware
import { create } from "zustand";
import { persist } from "zustand/middleware";
interface SettingsStore {
theme: "light" | "dark";
language: string;
setTheme: (theme: "light" | "dark") => void;
setLanguage: (language: string) => void;
}
const useSettingsStore = create<SettingsStore>()(
persist(
(set) => ({
theme: "light",
language: "en",
setTheme: (theme) => set({ theme }),
setLanguage: (language) => set({ language }),
}),
{
name: "settings-storage", // localStorage key
}
)
);
Selectors (Zustand 5)
// ✅ Select specific fields to prevent unnecessary re-renders
function UserName() {
const name = useUserStore((state) => state.name);
return <span>{name}</span>;
}
// ✅ For multiple fields, use useShallow
import { useShallow } from "zustand/react/shallow";
function UserInfo() {
const { name, email } = useUserStore(
useShallow((state) => ({ name: state.name, email: state.email }))
);
return <div>{name} - {email}</div>;
}
// ❌ AVOID: Selecting entire store (causes re-render on any change)
const store = useUserStore(); // Re-renders on ANY state change
Async Actions
interface UserStore {
user: User | null;
loading: boolean;
error: string | null;
fetchUser: (id: string) => Promise<void>;
}
const useUserStore = create<UserStore>((set) => ({
user: null,
loading: false,
error: null,
fetchUser: async (id) => {
set({ loading: true, error: null });
try {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
set({ user, loading: false });
} catch (error) {
set({ error: "Failed to fetch user", loading: false });
}
},
}));
Slices Pattern
// userSlice.ts
interface UserSlice {
user: User | null;
setUser: (user: User) => void;
clearUser: () => void;
}
const createUserSlice = (set): UserSlice => ({
user: null,
setUser: (user) => set({ user }),
clearUser: () => set({ user: null }),
});
// cartSlice.ts
interface CartSlice {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
}
const createCartSlice = (set): CartSlice => ({
items: [],
addItem: (item) => set((state) => ({ items: [...state.items, item] })),
removeItem: (id) => set((state) => ({
items: state.items.filter(i => i.id !== id)
})),
});
// store.ts
type Store = UserSlice & CartSlice;
const useStore = create<Store>()((...args) => ({
...createUserSlice(...args),
...createCartSlice(...args),
}));
Immer Middleware
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
interface TodoStore {
todos: Todo[];
addTodo: (text: string) => void;
toggleTodo: (id: string) => void;
}
const useTodoStore = create<TodoStore>()(
immer((set) => ({
todos: [],
addTodo: (text) => set((state) => {
// Mutate directly with Immer!
state.todos.push({ id: crypto.randomUUID(), text, done: false });
}),
toggleTodo: (id) => set((state) => {
const todo = state.todos.find(t => t.id === id);
if (todo) todo.done = !todo.done;
}),
}))
);
DevTools
import { create } from "zustand";
import { devtools } from "zustand/middleware";
const useStore = create<Store>()(
devtools(
(set) => ({
// store definition
}),
{ name: "MyStore" } // Name in Redux DevTools
)
);
Outside React
// Access store outside components
const { count, increment } = useCounterStore.getState();
increment();
// Subscribe to changes
const unsubscribe = useCounterStore.subscribe(
(state) => console.log("Count changed:", state.count)
);
When not to use it
- →When application state is strictly ephemeral and local to components
- →When using heavy frameworks that require global context providers
Prerequisites
Limitations
- →Store architecture can become complex with many deep slices
- →Limited by browser storage capacity for persistent state
How it compares
It enforces performance-first selection patterns that prevent full-store subscription re-renders.
Compared to similar skills
zustand-5 side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| zustand-5 (this skill) | 8 | 7mo | No flags | Beginner |
| zustand | 113 | 2mo | No flags | Intermediate |
| react | 34 | 2mo | No flags | Intermediate |
| react-component-patterns | 3 | 1mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by prowler-cloud
View all by prowler-cloud →You might also like
zustand
lobehub
Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
react
lobehub
React component development guide. Use when working with React components (.tsx files), creating UI, using @lobehub/ui components, implementing routing, or building frontend features. Triggers on React component creation, modification, layout implementation, or navigation tasks.
react-component-patterns
HoangNguyen0403
Modern React component architecture and composition patterns.
1k-state-management
OneKeyHQ
Jotai state management patterns — atoms, globalAtom, contextAtom, and persistence.
react-router-getting-started
ssrjkk
Getting Started for React-Router: initial setup and first steps
accessibility-compliance
wshobson
Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.