From harness-claude
Integrates Zustand stores with Redux DevTools for time-travel debugging, action inspection, and state tracing. Useful for debugging state changes and unexpected updates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:state-zustand-devtoolsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Debug Zustand stores with Redux DevTools integration for time-travel debugging and action inspection
Debug Zustand stores with Redux DevTools integration for time-travel debugging and action inspection
devtools middleware from zustand/middleware.name option to identify the store in the DevTools panel (especially when using multiple stores).set() — this shows descriptive action names instead of "anonymous".devtools should be the outermost wrapper.enabled option.// stores/todo-store.ts
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
interface TodoStore {
todos: Array<{ id: string; text: string; done: boolean }>;
addTodo: (text: string) => void;
toggleTodo: (id: string) => void;
removeTodo: (id: string) => void;
}
export const useTodoStore = create<TodoStore>()(
devtools(
(set) => ({
todos: [],
addTodo: (text) =>
set(
(state) => ({
todos: [...state.todos, { id: crypto.randomUUID(), text, done: false }],
}),
false, // replace: false (default merge behavior)
'todos/addTodo' // Action name shown in DevTools
),
toggleTodo: (id) =>
set(
(state) => ({
todos: state.todos.map((t) => (t.id === id ? { ...t, done: !t.done } : t)),
}),
false,
'todos/toggleTodo'
),
removeTodo: (id) =>
set(
(state) => ({ todos: state.todos.filter((t) => t.id !== id) }),
false,
'todos/removeTodo'
),
}),
{ name: 'TodoStore', enabled: process.env.NODE_ENV === 'development' }
)
);
Middleware stacking order: When combining multiple middlewares, order matters. The outermost middleware wraps everything:
// Correct order: devtools > persist > immer (outermost to innermost)
create<Store>()(
devtools(
persist(
immer((set) => ({
/* ... */
})),
{ name: 'storage-key' }
),
{ name: 'StoreName' }
)
);
Named actions: The third argument to set(state, replace, actionName) appears in the Redux DevTools action log. Without it, every action shows as "anonymous" which makes debugging difficult. Use a slice/action naming convention.
Multiple stores: Each store with devtools appears as a separate instance in the Redux DevTools dropdown. Use distinct name values.
Time-travel debugging: Redux DevTools supports jumping to any previous state. This works with Zustand's devtools middleware — clicking a past action restores the store to that point.
Production safety: Either use enabled: false in production or strip the middleware entirely:
const middlewares = (f: StateCreator<Store>) =>
process.env.NODE_ENV === 'development' ? devtools(f, { name: 'Store' }) : f;
export const useStore = create<Store>()(
middlewares((set) => ({
/* ... */
}))
);
https://zustand.docs.pmnd.rs/middlewares/devtools
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeCreates and manages Zustand stores with selectors, persistence, devtools, and middleware. Useful for global state in React or vanilla JavaScript.
Implements Zustand middleware for persistence (persist), devtools integration, Immer immutability, and custom store enhancements. Guides composition, best practices, partialize, and migrations.
Creates Zustand stores using TypeScript with subscribeWithSelector middleware, separate state/action interfaces, and individual selectors for optimized re-renders.