jpskill.com
📦 その他 コミュニティ

zustand-store-scaffold

Zustandという状態管理ライブラリで、コンポーネント単位やスライス単位のストアを、クラスベースで構築するための足場(ひな形)を生成し、定義へのジャンプやプライベートフィールドによるカプセル化、安全なスライスの組み合わせなどを実現するSkill。

📜 元の英語説明(参考)

Scaffold class-based Zustand stores with flattenActions: web (component-level store + Context + Provider) and core (slice-based store with immer). Class-based actions provide Go-to-Definition DX, #private field encapsulation, and prototype-safe slice composition.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Zustandという状態管理ライブラリで、コンポーネント単位やスライス単位のストアを、クラスベースで構築するための足場(ひな形)を生成し、定義へのジャンプやプライベートフィールドによるカプセル化、安全なスライスの組み合わせなどを実現するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o zustand-store-scaffold.zip https://jpskill.com/download/9724.zip && unzip -o zustand-store-scaffold.zip && rm zustand-store-scaffold.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9724.zip -OutFile "$d\zustand-store-scaffold.zip"; Expand-Archive "$d\zustand-store-scaffold.zip" -DestinationPath $d -Force; ri "$d\zustand-store-scaffold.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して zustand-store-scaffold.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → zustand-store-scaffold フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Zustand Store Scaffold

プロトタイプセーフなスライス合成のために、flattenActions を使用して型安全なクラスベースの Zustand ストアを生成します。

クイックスタート

Web パターン (コンポーネントレベルのストア)

python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
  --pattern web \
  --name ToolList \
  --path web/src/pages/_components/ToolList/store

生成されるファイル:

  • types.tsStoreSetter<T> 型定義
  • utils/flattenActions.ts — プロトタイプセーフなアクション平坦化関数
  • index.tsActionImpl + flattenActions を持つクラスベースのストア
  • context.ts — React Context と型付き useContext フック
  • provider.tsx — メモ化された Provider コンポーネント

Core パターン (スライスベースのストア)

単一スライス:

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

複数スライス (インタラクティブ):

python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
  --pattern core \
  --name AppStore \
  --path src/store
# プロンプト: Enter slice names (comma-separated, or press Enter for 'core'):
# 入力例: auth,user,ui

複数スライス (直接指定):

python3 ~/.claude/skills/zustand-store-scaffold/scripts/scaffold_zustand_store.py \
  --pattern core \
  --name AppStore \
  --path src/store \
  --slices auth,user,ui

生成されるファイル:

  • types.tsStoreSetter<T> 型定義
  • utils/flattenActions.ts — プロトタイプセーフなアクション平坦化関数
  • index.tsflattenActions スライス合成を持つストアファクトリ
  • slices/[name].tsActionImpl + #private フィールドを持つクラスベースのスライス

オプション

オプション 必須 説明
--pattern Yes ストアパターン (web または core) --pattern web
--name Yes PascalCase でのストア名 --name ToolList
--path Yes ターゲットディレクトリパス --path src/store
--slices No カンマ区切りのスライス名 (core のみ) --slices auth,user,ui
--force No 既存のファイルを上書き --force

注: --slices なしの core パターンの場合、スクリプトはスライス名をインタラクティブに尋ねます。共有ファイル (types.ts, utils/flattenActions.ts) は、すでに存在する場合はスキップされます (--force を指定しない限り)。

適切なパターンの選択

パターン 使用場面 場所パターン スライス
web Provider を持つコンポーネントレベルの状態 web/src/pages/_components/**/store N/A
core スライスを持つ同型/共有状態 packages/**/store 単一または複数

複数スライスを使用する場合 (Core パターン)

複数のスライスを使用して、機能ドメインごとに複雑な状態を整理します。

シナリオ 推奨スライス
認証アプリ auth, user, session
Eコマースストア cart, products, user, ui
ダッシュボード data, filters, ui, settings
チャットアプリケーション messages, contacts, ui, notifications

生成されるファイル

ファイル 目的
types.ts StoreSetter<T> — Zustand の内部構造に一致する型安全なオーバーロードされたセッター
utils/flattenActions.ts flattenActions<T> — プロトタイプチェーンをたどり、メソッドをバインドし、クラスインスタンスをマージします
index.ts 初期状態 + flattenActions 合成を組み合わせたストアファクトリ
slices/*.ts (core) #set/#get を持つ *ActionImpl クラス、create*Slice 経由でエクスポート
context.ts (web) React Context + 型付きセレクターフック
provider.tsx (web) 参照安定なストア作成を持つメモ化された Provider

生成後のステップ

  1. *SliceState インターフェース (core) または *StoreState インターフェース (web) で 状態を定義 します。

    export interface CoreSliceState {
      agents: Agent[]
      selectedId: string | null
    }
  2. *ActionImpl クラスに アクションメソッドを追加 します (アロー関数として)。

    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)
      }
    }
  3. ストアファクトリまたは設定で 初期状態を設定 します。

    const store = createCoreAgentStore({
      initialState: { agents: [], selectedId: null }
    })

使用例

Web ストアの使用例

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)
  // setToolList で Go to Definition → ActionImpl メソッドに直接移動
}

Core ストアの使用例

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/class-based-pattern.md を参照してください。
  • 完全なコード例については、references/store-patterns.md を参照してください。
  • 参照 PR: lobehub#12081
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

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.tsStoreSetter<T> type definition
  • utils/flattenActions.ts — Prototype-safe action flattener
  • index.ts — Class-based store with ActionImpl + flattenActions
  • context.ts — React Context and typed useContext hook
  • provider.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.tsStoreSetter<T> type definition
  • utils/flattenActions.ts — Prototype-safe action flattener
  • index.ts — Store factory with flattenActions slice composition
  • slices/[name].ts — Class-based slice with ActionImpl + #private fields

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

  1. Define state in *SliceState interface (core) or *StoreState interface (web):

    export interface CoreSliceState {
      agents: Agent[]
      selectedId: string | null
    }
  2. Add action methods as arrow functions in *ActionImpl class:

    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)
      }
    }
  3. 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.md for detailed pattern documentation
  • See references/store-patterns.md for complete code examples
  • Reference PR: lobehub#12081