
Zustand 5
- 847 installs
- 14.5k repo stars
- Updated August 4, 2026
- prowler-cloud/prowler
zustand-5 is an agent skill that provides Zustand 5 store, selector, persist middleware, and slice patterns for developers building reactive client-side UIs with coding agents in TypeScript React codebases.
About
zustand-5 is a skill from prowler-cloud/prowler at metadata version 1.0 scoped to root and ui directories with Apache-2.0 license. It triggers when implementing client-side state with Zustand stores, selectors, persist middleware, and slices. Allowed tools include Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, and Task. The readme documents a typed create() counter store with increment, decrement, and reset actions. Developers reach for zustand-5 when they need reliable Zustand 5-specific patterns rather than generic state-management advice.
- Generates type-safe Zustand stores with create() and set() patterns
- Implements persist middleware for theme, language and user settings
- Creates slices, selectors and custom hooks for complex state
- Supports middleware composition and immer for immutable updates
- Trigger: When implementing client-side state with Zustand (stores, selectors, persist middleware, slices)
Zustand 5 by the numbers
- 847 all-time installs (skills.sh)
- +37 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #432 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/prowler-cloud/prowler --skill zustand-5Add your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 847 |
|---|---|
| repo stars | ★ 14.5k |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | prowler-cloud/prowler ↗ |
How do you implement Zustand 5 stores with persist middleware?
Get reliable Zustand 5 patterns for client-side state, selectors, persistence, and slices when building reactive UIs with agents.
Who is it for?
Frontend developers on Zustand 5 who need persist middleware, slices, and selector patterns in TypeScript React UIs.
Skip if: Projects still on Zustand 3/4 APIs or backends with no client-side React state requirements.
When should I use this skill?
The user implements client-side state with Zustand 5 stores, selectors, persist middleware, or slices.
What you get
Typed Zustand 5 stores, persist middleware config, slice modules, and selector-optimized React hooks.
- zustand 5 store module
- persist middleware config
- slice-based store layout
By the numbers
- Skill metadata version 1.0
- Scoped to root and ui directories
Files
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 changeAsync 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)
);Related skills
How it compares
Choose zustand-5 for version-5 persist and slice APIs; choose zustand-state-management for broader React/Next.js Zustand conventions.
FAQ
What triggers the zustand-5 skill?
The zustand-5 skill triggers when implementing client-side state with Zustand 5 stores, selectors, persist middleware, or slices. Metadata version 1.0 scopes the skill to root and ui paths in the prowler repository.
Which tools can zustand-5 use?
zustand-5 may use Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, and Task tools while applying Zustand 5 patterns for stores, selectors, persistence, and slice modules in TypeScript React UIs.
Is Zustand 5 safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.