zustand-store-scaffold
Zustand Store Scaffold
Generate type-safe class-based Zustand stores with flattenActions for prototype-safe slice composition.
Quick Start
Web Pattern (Component-level Store)
python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
--pattern web \
--name ToolList \
--path web/src/pages/_components/ToolList/store
Generates:
types.ts—StoreSetter<T>type definitionutils/flattenActions.ts— Prototype-safe action flattenerindex.ts— Class-based store withActionImpl+flattenActionscontext.ts— React Context and typeduseContexthookprovider.tsx— Memo-wrapped Provider component
Core Pattern (Slice-based Store)
Single Slice:
python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
--pattern core \
--name CoreAgent \
--path packages/ag-ui-view/src/core/helpers/isomorphic/store
Multiple Slices (Interactive):
python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
--pattern core \
--name AppStore \
--path src/store
# Will prompt: Enter slice names (comma-separated, or press Enter for 'core'):
# Example input: auth,user,ui
Multiple Slices (Direct):
python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
--pattern core \
--name AppStore \
--path src/store \
--slices auth,user,ui
Generates:
types.ts—StoreSetter<T>type definitionutils/flattenActions.ts— Prototype-safe action flattenerindex.ts— Store factory withflattenActionsslice compositionslices/[name].ts— Class-based slice withActionImpl+#privatefields
Options
| Option | Required | Description | Example |
|---|---|---|---|
--pattern |
Yes | Store pattern (web or core) |
--pattern web |
--name |
Yes | Store name in PascalCase | --name ToolList |
--path |
Yes | Target directory path | --path src/store |
--slices |
No | Comma-separated slice names (core only) | --slices auth,user,ui |
--force |
No | Overwrite existing files | --force |
Note: For core pattern without --slices, the script interactively asks for slice names. Shared files (types.ts, utils/flattenActions.ts) are skipped if they already exist (unless --force).
Choose the Right Pattern
| Pattern | Use When | Location Pattern | Slices |
|---|---|---|---|
| web | Component-level state with Provider | web/src/pages/_components/**/store |
N/A |
| core | Isomorphic/shared state with slices | packages/**/store |
Single or multiple |
When to Use Multiple Slices (Core Pattern)
Use multiple slices to organize complex state by feature domains:
| Scenario | Recommended Slices |
|---|---|
| Authentication app | auth, user, session |
| E-commerce store | cart, products, user, ui |
| Dashboard | data, filters, ui, settings |
| Chat application | messages, contacts, ui, notifications |
Generated Files
| File | Purpose |
|---|---|
types.ts |
StoreSetter<T> — type-safe overloaded setter matching Zustand internals |
utils/flattenActions.ts |
flattenActions<T> — walks prototype chain, binds methods, merges class instances |
index.ts |
Store factory combining initial state + flattenActions composition |
slices/*.ts (core) |
*ActionImpl class with #set/#get, exported via create*Slice |
context.ts (web) |
React Context + typed selector hook |
provider.tsx (web) |
Memo-wrapped Provider with ref-stable store creation |
Post-Generation Steps
-
Define state in
*SliceStateinterface (core) or*StoreStateinterface (web):export interface CoreSliceState { agents: Agent[] selectedId: string | null } -
Add action methods as arrow functions in
*ActionImplclass:export class CoreActionImpl { readonly #set: StoreSetter<CoreSlice> readonly #get: () => CoreSlice // ...constructor selectAgent = (id: string): void => { this.#set({ selectedId: id }) } getSelectedAgent = (): Agent | undefined => { const { agents, selectedId } = this.#get() return agents.find((a) => a.id === selectedId) } } -
Set initial state in the store factory or config:
const store = createCoreAgentStore({ initialState: { agents: [], selectedId: null } })
Usage Examples
Web Store Usage
import Provider from './store/provider'
import { useToolListContext } from './store/context'
function ToolListPage() {
return (
<Provider>
<ToolListContent />
</Provider>
)
}
function ToolListContent() {
const toolList = useToolListContext((s) => s.toolList)
const setToolList = useToolListContext((s) => s.setToolList)
// Go to Definition on setToolList → lands directly on ActionImpl method
}
Core Store Usage
import { createCoreAgentStore } from './store'
const store = createCoreAgentStore({
initialState: { agents: [], selectedId: null }
})
// Vanilla JS
const state = store.getState()
state.selectAgent('agent-1')
// React (with useStore)
import { useStore } from 'zustand'
function AgentList() {
const agents = useStore(store, (s) => s.agents)
const selectAgent = useStore(store, (s) => s.selectAgent)
}
References
- See
references/class-based-pattern.mdfor detailed pattern documentation - See
references/store-patterns.mdfor complete code examples - Reference PR: lobehub#12081
More from adonis0123/adonis-skills
staged-changes-review
Checklist-driven review of staged Git changes with deterministic rule scanning and semantic analysis. Use when the user wants to review staged changes, check for errors before commit, or validate code quality before committing.
25ruler-rules-init
Migrate and bootstrap Ruler-based AI rules across repositories with English-first templates, preset-based project detection, and safe, idempotent setup. Use when creating or standardizing `.ruler/*` files, generating `AGENTS.md`/`CLAUDE.md`, wiring `ruler:apply` into `package.json`, adding generated-file ignores in `.gitignore`, and designing `applyTo` scoping patterns such as `**` and `web/**`.
18discuss-before-plan
Enforces 'decide then plan' discipline - the pre-planning decision gate. Use when the user asks for a plan or starts a change while key decisions are unresolved: architecture tradeoffs, data flow, public interfaces, unclear requirements, multi-module scope, or roughly 5+ files affected. Also triggers when the user explicitly wants to discuss, compare options, or review architecture before committing. Core job: reduce incorrect-execution cost by confirming decisions before producing executable plans.
17claude-skills-sync-init
Bootstrap Claude skill-sync automation in any repository. Use when users ask to set up `.agents/skills` to `.claude/skills` syncing, generate `skills:sync:*` scripts, inject package.json scripts/postinstall hooks, or initialize this sync workflow in a new or existing project.
16staged-review-validator
Validate staged-changes-review findings with evidence-based verdicts and minimal-fix guidance. Use when you need to confirm whether each reported issue is valid and actionable.
14tailwindcss-next-init
Initialize Tailwind CSS v4 and Iconify for Next.js App Router projects with script-driven templates. Use when you need a fast setup or migration with consistent style-entry conventions.
12