AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

State Management

skill-komluk-scaffolding-state-management · by komluk

Client state management standards: local-vs-global decisions, store structure, selectors, and re-render performance. TRIGGER when: creating a store, managing global state, or deciding local vs global state. SKIP: component/hook structure (use react-patterns); visual styling (use mui-styling). (Examples use Zustand.)

No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-komluk-scaffolding-state-management

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-komluk-scaffolding-state-management)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of State Management? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

State Management Skill

Client state management standards and best practices. The universal guidance (local-vs-global decisions, store structure, selectors, performance) applies to any store library; the concrete code examples use Zustand.

When to Apply

  • Creating new state stores
  • Sharing state between components
  • State architecture decisions
  • Performance optimization for state

State Category Guidelines

| Category | Solution | Use When | |----------|----------|----------| | Local UI | useState | Single component, simple state | | Shared UI | Zustand store | Multiple components need same data | | Server data | React Query / SWR | API data with caching needs | | Form state | useState / form library | Form inputs, validation | | URL state | useSearchParams | Filter/sort params, shareable URLs |


Zustand Store Standards

Store Structure

| Element | Requirement | |---------|-------------| | Interface | Define typed state + actions interface | | State | Group related state together | | Actions | Define all mutations as functions | | Naming | use[Domain]Store convention |

Store Design Principles

| Principle | Description | |-----------|-------------| | Single responsibility | One store per domain (projects, UI, settings) | | Flat structure | Avoid deeply nested state | | Immutable updates | Always return new objects | | Colocated actions | Keep actions inside store definition |


Selector Best Practices

Selection Rules

| Rule | Reason | |------|--------| | Select minimal data | Reduces re-renders | | Use shallow for objects | Prevents unnecessary updates | | Memoize derived data | Use useMemo for computed values | | Avoid selecting entire store | Causes re-render on any change |

Selector Patterns

| Pattern | Use Case | |---------|----------| | Single value | (state) => state.count | | Multiple values | (state) => ({ a: state.a, b: state.b }), shallow | | Derived value | useMemo outside store |


Middleware Usage

| Middleware | Purpose | When to Use | |------------|---------|-------------| | persist | LocalStorage persistence | User preferences, settings | | devtools | Redux DevTools integration | Development debugging | | immer | Immutable updates | Complex nested state | | subscribeWithSelector | Granular subscriptions | Performance optimization |


Store Organization

File Structure

src/stores/
├── index.ts           # Re-exports all stores
├── projectStore.ts    # Domain-specific store
├── uiStore.ts         # UI state (modals, panels)
└── settingsStore.ts   # User preferences

Store Separation Guidelines

| Store Type | Contains | |------------|----------| | Domain store | Business entities, selections | | UI store | Modal states, panel visibility, loading | | Settings store | User preferences, persisted config |


Performance Guidelines

DO

  • Select only needed state slices
  • Use shallow equality for object selections
  • Define actions inside store (stable references)
  • Split large stores by domain
  • Use subscribeWithSelector for side effects

DON'T

  • Select entire store object
  • Create new objects in selectors without shallow
  • Put derived/computed state in store
  • Call actions during render phase
  • Create deeply nested store structure

Anti-Patterns

| Anti-Pattern | Problem | Solution | |--------------|---------|----------| | Giant store | Hard to maintain, performance issues | Split by domain | | Computed in store | Stale data, extra complexity | Use useMemo | | Prop drilling | Bypasses store benefits | Use store directly | | Store in useState | Loses reactivity | Use store hook | | No TypeScript | Runtime errors | Define interfaces |


Decision Matrix

| Scenario | Recommended Solution | |----------|---------------------| | Form input state | useState | | Modal open/close | useState or UI store | | Selected item (shared) | Domain store | | User preferences | Persisted store | | API response data | Store + service function | | Computed/derived data | useMemo from store values | | Global loading state | UI store |


Example: Zustand Store Patterns (illustrative)

> Illustrative — these are one team's concrete Zustand conventions shown as an > example. Substitute your store library's equivalents (Redux Toolkit, Jotai, > Pinia, signals, etc.). The decision matrix and selector/performance guidance > above are the reusable, library-agnostic part.

Store Files (/)

| Store | Persist | Purpose | |-------|---------|---------| | workspaceStore.ts | Yes (scaffolding-workspaces) | Projects/workspaces, active selection | | taskStore.ts | No | Task CRUD, SSE updates, agent statuses | | authStore.ts | Yes (auth-storage) | GitHub OAuth state, user profile |

Type Pattern: Separate State & Actions

Every store defines type XxxState and type XxxActions, then exports the combined type:

type WorkspaceState = {
  workspaces: Workspace[];
  activeWorkspace: Workspace | null;
};
type WorkspaceActions = {
  addWorkspace: (pathOrWorkspace: string | Workspace) => void;
  removeWorkspace: (path: string) => Promise;
  setActiveWorkspace: (path: string) => void;
  loadFromApi: () => Promise;
};
export type WorkspaceStore = WorkspaceState & WorkspaceActions;

Persist Middleware with partialize

Persisted stores use partialize to exclude actions and transient state from storage:

export const useWorkspaceStore = create()(
  persist(
    (set, get) => ({ /* state + actions */ }),
    {
      name: 'scaffolding-workspaces',
      partialize: (state) => ({
        workspaces: state.workspaces,
        activeWorkspace: state.activeWorkspace,
      }),
    }
  )
);

Hook Wrappers with useShallow (/)

Stores are consumed through hook wrappers that use useShallow to prevent re-renders:

import { useWorkspaceStore } from '../stores/workspaceStore';
import { useShallow } from 'zustand/shallow';

export function useWorkspace() {
  return useWorkspaceStore(
    useShallow((state) => ({
      workspaces: state.workspaces,
      activeWorkspace: state.activeWorkspace,
      addWorkspace: state.addWorkspace,
      // ... selected fields only
    }))
  );
}

API Sync Pattern (loadFromApi)

Stores hydrate from localStorage first, then enrich from API:

  1. persist middleware loads cached state from localStorage on mount
  2. loadFromApi() fetches from backend, merges fields (id, github_url, role) into existing entries
  3. Failures are silently caught - localStorage data still works offline

SSE Update Pattern (taskStore)

Non-persisted stores receive real-time updates from Server-Sent Events:

  • addTask(task) - deduplicates before prepending to list
  • updateTask(task) - replaces full task object in list and currentTask
  • updateTaskPartial(id, updates) - merges partial fields from SSE completion events
  • updateAgentStatus(taskId, status) - tracks per-agent progress within a task

Error Handling in Stores

Stores use extractErrorMessage(err, fallbackMsg) utility and store errors in state:

catch (err) {
  const message = extractErrorMessage(err, 'Failed to fetch tasks');
  set({ error: message, isLoading: false });
}

For expected errors (e.g., 409 conflict on cancel), check AxiosError status before setting error state.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.