skills/state/SKILL.md
State management design. Frontend state, server state, state machines, optimistic updates, caching.
npx skillsauth add arbazkhan971/godmode stateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
/godmode:state, "manage state", "global state"# Detect state libraries
grep -r "from 'redux\|from 'zustand\|from 'jotai\|from '@tanstack/react-query\|from 'pinia" \
src/ --include="*.ts" --include="*.tsx" -l 2>/dev/null
# Count state files
find src/ -name "*.store.*" -o -name "*.slice.*" \
-o -name "*.atom.*" -o -name "*Store.*" \
2>/dev/null | wc -l
STATE AUDIT:
Framework: <React | Vue | Svelte | Angular>
State libs: <Redux | Zustand | Jotai | Pinia>
Server state: <React Query | SWR | Apollo | none>
Form state: <React Hook Form | Formik | none>
Persistence: <localStorage | IndexedDB | none>
| Category | Lifetime | Tool |
|-------------|-----------|----------------------|
| Server | Cache | React Query, SWR |
| Client (UI) | Session | Zustand, Jotai, Pinia|
| Client (app)| Session | Zustand, Redux, MobX |
| URL | Navigation| Router search params |
| Form | Interaction| React Hook Form |
| Persistent | Forever | localStorage + Zustand|
IF data comes from server: it is server state.
Do NOT put it in Redux/Zustand/Pinia.
Use React Query, SWR, or Apollo.
This single decision eliminates 80% of complexity.
| Criteria | Redux TK | Zustand | Jotai | Pinia |
|------------|---------|---------|-------|-------|
| Bundle | ~11KB | ~1KB | ~2KB | ~2KB |
| Boilerplate| Medium | Low | Low | Low |
| DevTools | Excellent| Good | Good | Excellent|
| TypeScript | Excellent| Excellent|Excellent|Excellent|
IF React + simple state: Zustand (1KB, minimal)
IF React + atomic state: Jotai (bottom-up)
IF React + complex state + devtools: Redux TK
IF Vue 3: Pinia (official, TypeScript-first)
IF need middleware/saga: Redux TK
IF REST API: React Query (best cache control)
IF GraphQL: Apollo Client (normalized cache)
IF already using Redux: RTK Query (integrated)
WHEN optimistic updates needed: React Query or Apollo
(both have built-in support)
Root:
├── server state (React Query)
│ ├── ['users', userId]
│ ├── ['products', filters]
│ └── ['orders', { page, limit }]
├── client state (Zustand)
│ ├── uiStore (sidebar, modals, theme)
│ ├── cartStore (items, quantities)
│ └── authStore (session, user)
└── URL state (router)
└── search params, pagination
QUERY KEY FACTORY per entity:
entity.all -> ['entity']
entity.lists() -> ['entity', 'list']
entity.list(filters) -> ['entity', 'list', filters]
entity.detail(id) -> ['entity', 'detail', id]
QUERY CONFIG:
staleTime: 5 min (how long data is fresh)
gcTime: 30 min (cache retention)
enabled: !!userId (conditional fetch)
MUTATION onSuccess:
1. setQueryData for optimistic single-entity
2. invalidateQueries for list refresh
IF optimistic: onMutate saves snapshot,
onError restores snapshot (rollback)
USE state machine (XState) when:
[x] Fixed set of states (loading/success/error)
[x] Strict transition rules
[x] Invalid combinations possible
[x] Branching workflows (checkout flow)
[x] WebSocket lifecycle management
DO NOT use when:
[ ] Simple boolean toggle
[ ] Free-form text input
[ ] List of items (use array state)
| Storage | Capacity | Speed | Use Case |
|---------------|----------|-------|-------------|
| localStorage | ~5-10MB | Sync | Theme, prefs|
| sessionStorage| ~5-10MB | Sync | Form drafts |
| IndexedDB | ~50MB+ | Async | Large data |
SSR HYDRATION:
1. Server reads initial state
2. Pass to client StoreHydrator component
3. setState once via useRef guard
4. Never read persisted state during SSR
5. hasHydrated flag prevents flash
grep -E "redux|zustand|jotai|pinia|vuex|mobx" \
package.json 2>/dev/null
grep -E "@tanstack/react-query|swr|@apollo/client" \
package.json 2>/dev/null
Log to .godmode/state-results.tsv:
timestamp\tstore\ttype\ttool\tselectors\ttests\tstatus
STATE: {framework}. Server: {tool}. Client: {tool}.
Stores: {N}. Selectors: {N}. Tests: {status}.
KEEP if: tests pass AND no re-render regressions
AND no full-store subscriptions
DISCARD if: tests fail OR re-renders increased
OR new derived state stored
STOP when:
- Server/client state separated
- All subscriptions use selectors
- Tests pass, no sensitive data in localStorage
- User requests stop OR max 10 iterations
development
Web performance optimization. Lighthouse, bundle analysis, code splitting, image optimization, critical CSS, fonts, service workers, CDN.
development
Webhook design, delivery, retry, HMAC verification, event subscriptions, dead letter queues.
development
Vue.js mastery. Composition API, Pinia, Vue Router, Nuxt SSR/SSG, Vite optimization, testing.
development
Evidence gate. Run command, read full output, confirm or deny claim. No trust, only proof.